// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot 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.
// Polkadot 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 Polkadot. If not, see .
//! Adapters to work with [`frame_support::traits::fungibles`] through XCM.
use crate::{AssetChecking, MintLocation};
use frame_support::{
ensure,
traits::{tokens::nonfungibles, Get},
};
use sp_std::{marker::PhantomData, prelude::*, result};
use xcm::latest::prelude::*;
use xcm_executor::traits::{
ConvertLocation, Error as MatchError, MatchesNonFungibles, TransactAsset,
};
const LOG_TARGET: &str = "xcm::nonfungibles_adapter";
pub struct NonFungiblesTransferAdapter(
PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>,
);
impl<
Assets: nonfungibles::Transfer,
Matcher: MatchesNonFungibles,
AccountIdConverter: ConvertLocation,
AccountId: Clone, // can't get away without it since Currency is generic over it.
> TransactAsset for NonFungiblesTransferAdapter
{
fn transfer_asset(
what: &Asset,
from: &Location,
to: &Location,
context: &XcmContext,
) -> result::Result {
log::trace!(
target: LOG_TARGET,
"transfer_asset what: {:?}, from: {:?}, to: {:?}, context: {:?}",
what,
from,
to,
context,
);
// 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| XcmError::FailedToTransactAsset(e.into()))?;
Ok(what.clone().into())
}
}
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