difftreelog
feat xcm nft support
in: master
5 files changed
pallets/common/src/lib.rsdiffbeforeafterboth2351 /// Is the collection a foreign one?2351 /// Is the collection a foreign one?2352 fn is_foreign(&self) -> bool;2352 fn is_foreign(&self) -> bool;23532354 /// Does the token have children?2355 fn token_has_children(&self, _token: TokenId) -> bool {2356 false2357 }235323582354 /// Create a collection's item using a transaction.2359 /// Create a collection's item using a transaction.2355 ///2360 ///pallets/foreign-assets/src/lib.rsdiffbeforeafterboth--- a/pallets/foreign-assets/src/lib.rs
+++ b/pallets/foreign-assets/src/lib.rs
@@ -364,7 +364,7 @@
fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {}
- fn deposit_asset(what: &MultiAsset, to: &MultiLocation, context: &XcmContext) -> XcmResult {
+ fn deposit_asset(what: &MultiAsset, to: &MultiLocation, _context: &XcmContext) -> XcmResult {
let collection_id = Self::multiasset_to_collection(what)?;
let dispatch =
T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;
@@ -397,7 +397,42 @@
from: &MultiLocation,
_maybe_context: Option<&XcmContext>,
) -> Result<staging_xcm_executor::Assets, XcmError> {
- Err(XcmError::Unimplemented)
+ let from = T::LocationToAccountId::convert_location(from)
+ .ok_or(XcmExecutorError::AccountIdConversionFailed)?;
+
+ let collection_id = Self::multiasset_to_collection(what)?;
+ let dispatch =
+ T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;
+
+ let collection = dispatch.as_dyn();
+ let xcm_ext = collection.xcm_extensions().ok_or(XcmError::NoPermission)?;
+
+ match what.fun {
+ Fungibility::Fungible(amount) => xcm_ext
+ .burn_item(from, TokenId::default(), amount)
+ .map_err(|_| XcmError::FailedToTransactAsset("fungible item withdraw failed"))?,
+
+ Fungibility::NonFungible(asset_instance) => {
+ let token_id =
+ Self::asset_instance_to_token_id(xcm_ext, collection_id, &asset_instance)?
+ .ok_or(XcmError::AssetNotFound)?;
+
+ if xcm_ext.token_has_children(token_id) {
+ return Err(XcmError::Unimplemented);
+ }
+
+ let depositor = &from;
+ let to = Self::pallet_account();
+ let amount = 1;
+ xcm_ext
+ .transfer_item(depositor, &from, &to, token_id, amount, &ZeroBudget)
+ .map_err(|_| {
+ XcmError::FailedToTransactAsset("nonfungible item withdraw failed")
+ })?;
+ }
+ }
+
+ Ok(what.clone().into())
}
fn internal_transfer_asset(
@@ -406,7 +441,49 @@
to: &MultiLocation,
_context: &XcmContext,
) -> Result<staging_xcm_executor::Assets, XcmError> {
- Err(XcmError::Unimplemented)
+ let collection_id = Self::multiasset_to_collection(what)?;
+
+ let dispatch =
+ T::CollectionDispatch::dispatch(collection_id).map_err(|_| XcmError::AssetNotFound)?;
+ let collection = dispatch.as_dyn();
+ let xcm_ext = collection.xcm_extensions().ok_or(XcmError::NoPermission)?;
+
+ let from = T::LocationToAccountId::convert_location(from)
+ .ok_or(XcmExecutorError::AccountIdConversionFailed)?;
+
+ let to = T::LocationToAccountId::convert_location(to)
+ .ok_or(XcmExecutorError::AccountIdConversionFailed)?;
+
+ let depositor = &from;
+
+ match what.fun {
+ Fungibility::Fungible(amount) => xcm_ext
+ .transfer_item(
+ depositor,
+ &from,
+ &to,
+ TokenId::default(),
+ amount,
+ &ZeroBudget,
+ )
+ .map_err(|_| XcmError::FailedToTransactAsset("fungible item transfer failed"))?,
+
+ Fungibility::NonFungible(asset_instance) => {
+ let token_id =
+ Self::asset_instance_to_token_id(xcm_ext, collection_id, &asset_instance)?
+ .ok_or(XcmError::AssetNotFound)?;
+
+ let amount = 1;
+
+ xcm_ext
+ .transfer_item(depositor, &from, &to, token_id, amount, &ZeroBudget)
+ .map_err(|_| {
+ XcmError::FailedToTransactAsset("nonfungible item transfer failed")
+ })?;
+ }
+ }
+
+ Ok(what.clone().into())
}
}
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -95,9 +95,8 @@
use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec};
use up_data_structs::{
- budget::{Budget, ZeroBudget},
- mapping::TokenAddressMapping,
- AccessMode, CollectionId, CreateCollectionData, Property, PropertyKey, TokenId,
+ budget::Budget, mapping::TokenAddressMapping, AccessMode, CollectionId, Property, PropertyKey,
+ TokenId,
};
use weights::WeightInfo;
pallets/nonfungible/src/common.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -576,6 +576,10 @@
self.flags.foreign
}
+ fn token_has_children(&self, token: TokenId) -> bool {
+ <Pallet<T>>::token_has_children(self.id, token)
+ }
+
fn create_item_internal(
&self,
depositor: &<T>::CrossAccountId,
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -117,8 +117,8 @@
use sp_std::{collections::btree_map::BTreeMap, vec, vec::Vec};
use up_data_structs::{
budget::Budget, mapping::TokenAddressMapping, AccessMode, AuxPropertyValue, CollectionId,
- CreateCollectionData, CreateNftExData, CustomDataLimit, PropertiesPermissionMap, Property,
- PropertyKey, PropertyKeyPermission, PropertyScope, PropertyValue, TokenChild, TokenId,
+ CreateNftExData, CustomDataLimit, PropertiesPermissionMap, Property, PropertyKey,
+ PropertyKeyPermission, PropertyScope, PropertyValue, TokenChild, TokenId,
TokenProperties as TokenPropertiesT,
};
use weights::WeightInfo;