// 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 . use crate::traits::TransactAsset; use pezframe_support::traits::ContainsPair; use pezsp_runtime::codec::{Decode, DecodeWithMemTracking, Encode}; use scale_info::TypeInfo; use xcm::prelude::*; /// Errors related to determining asset transfer support. #[derive(Copy, Clone, Encode, Decode, Eq, PartialEq, Debug, TypeInfo)] pub enum Error { /// Reserve chain could not be determined for assets. UnknownReserve, } /// Specify which type of asset transfer is required for a particular `(asset, dest)` combination. #[derive(Clone, Encode, Decode, DecodeWithMemTracking, PartialEq, Debug, TypeInfo)] pub enum TransferType { /// should teleport `asset` to `dest` Teleport, /// should reserve-transfer `asset` to `dest`, using local chain as reserve LocalReserve, /// should reserve-transfer `asset` to `dest`, using `dest` as reserve DestinationReserve, /// should reserve-transfer `asset` to `dest`, using remote chain `Location` as reserve RemoteReserve(VersionedLocation), } /// A trait for identifying asset transfer type based on `IsTeleporter` and `IsReserve` /// configurations. pub trait XcmAssetTransfers { /// Combinations of (Asset, Location) pairs which we trust as reserves. Meaning /// reserve-based-transfers are to be used for assets matching this filter. type IsReserve: ContainsPair; /// Combinations of (Asset, Location) pairs which we trust as teleporters. Meaning teleports are /// to be used for assets matching this filter. type IsTeleporter: ContainsPair; /// How to withdraw and deposit an asset. type AssetTransactor: TransactAsset; /// Determine transfer type to be used for transferring `asset` from local chain to `dest`. fn determine_for(asset: &Asset, dest: &Location) -> Result { if Self::IsTeleporter::contains(asset, dest) { // we trust destination for teleporting asset return Ok(TransferType::Teleport); } else if Self::IsReserve::contains(asset, dest) { // we trust destination as asset reserve location return Ok(TransferType::DestinationReserve); } // try to determine reserve location based on asset id/location let asset_location = asset.id.0.chain_location(); if asset_location == Location::here() || Self::IsTeleporter::contains(asset, &asset_location) { // if the asset is local, then it's a local reserve // it's also a local reserve if the asset's location is not `here` but it's a location // where it can be teleported to `here` => local reserve Ok(TransferType::LocalReserve) } else if Self::IsReserve::contains(asset, &asset_location) { // remote location that is recognized as reserve location for asset Ok(TransferType::RemoteReserve(asset_location.into())) } else { // remote location that is not configured either as teleporter or reserve => cannot // determine asset reserve Err(Error::UnknownReserve) } } } impl XcmAssetTransfers for () { type IsReserve = (); type IsTeleporter = (); type AssetTransactor = (); fn determine_for(_: &Asset, _: &Location) -> Result { return Err(Error::UnknownReserve); } }