// Copyright (C) Parity Technologies (UK) Ltd. and Dijital Kurdistan Tech Institute
// This file is part of Pezkuwi.
// Pezkuwi is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Pezkuwi is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Pezkuwi. If not, see .
//! Adapters to work with [`pezframe_support::traits::tokens::nonfungibles`] through XCM.
use crate::{AssetChecking, MintLocation};
use core::{fmt::Debug, marker::PhantomData, result};
use pezframe_support::{
ensure,
traits::{tokens::nonfungibles, Get},
};
use xcm::latest::prelude::*;
use xcm_executor::traits::{
ConvertLocation, Error as MatchError, MatchesNonFungibles, TransactAsset,
};
const LOG_TARGET: &str = "xcm::nonfungibles_adapter";
/// [`TransactAsset`] implementation that allows the use of a [`nonfungibles`] implementation for
/// handling an asset in the XCM executor.
/// Only works for transfers.
pub struct NonFungiblesTransferAdapter(
PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>,
)
where
Assets: nonfungibles::Transfer,
Assets::CollectionId: Debug,
Assets::ItemId: Debug;
impl<
Assets: nonfungibles::Transfer,
Matcher: MatchesNonFungibles,
AccountIdConverter: ConvertLocation,
AccountId: Clone + Debug, // can't get away without it since Currency is generic over it.
> TransactAsset for NonFungiblesTransferAdapter
where
Assets::CollectionId: Debug,
Assets::ItemId: Debug,
{
fn transfer_asset(
what: &Asset,
from: &Location,
to: &Location,
context: &XcmContext,
) -> result::Result {
tracing::trace!(
target: LOG_TARGET,
?what,
?from,
?to,
?context,
"transfer_asset",
);
// Check we handle this asset.
let (class, instance) = Matcher::matches_nonfungibles(what)?;
let destination = AccountIdConverter::convert_location(to)
.ok_or(MatchError::AccountIdConversionFailed)?;
Assets::transfer(&class, &instance, &destination).map_err(|e| {
tracing::debug!(target: LOG_TARGET, ?e, ?class, ?instance, ?destination, "Failed to transfer asset");
XcmError::FailedToTransactAsset(e.into())
})?;
Ok(what.clone().into())
}
}
/// [`TransactAsset`] implementation that allows the use of a [`nonfungibles`] implementation for
/// handling an asset in the XCM executor.
/// Only works for teleport bookkeeping.
pub struct NonFungiblesMutateAdapter<
Assets,
Matcher,
AccountIdConverter,
AccountId,
CheckAsset,
CheckingAccount,
>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>);
impl<
Assets: nonfungibles::Mutate,
Matcher: MatchesNonFungibles,
AccountIdConverter: ConvertLocation,
AccountId: Clone + Eq, // can't get away without it since Currency is generic over it.
CheckAsset: AssetChecking,
CheckingAccount: Get