feat: Rebrand Polkadot/Substrate references to PezkuwiChain
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
@@ -0,0 +1,506 @@
|
||||
// Copyright (C) Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub mod benchmarks;
|
||||
mod erc20_transactor;
|
||||
pub mod foreign_creators;
|
||||
pub mod fungible_conversion;
|
||||
pub mod local_and_foreign_assets;
|
||||
pub mod matching;
|
||||
pub mod migrations;
|
||||
pub mod runtime_api;
|
||||
|
||||
pub use erc20_transactor::ERC20Transactor;
|
||||
|
||||
extern crate alloc;
|
||||
extern crate core;
|
||||
|
||||
use crate::matching::{LocalLocationPattern, ParentLocation};
|
||||
use alloc::vec::Vec;
|
||||
use codec::{Decode, EncodeLike};
|
||||
use core::{cmp::PartialEq, marker::PhantomData};
|
||||
use pezframe_support::traits::{Contains, Equals, EverythingBut};
|
||||
use pezsp_core::H160;
|
||||
use pezsp_runtime::traits::{MaybeEquivalence, TryConvertInto};
|
||||
use teyrchains_common::{AssetIdForTrustBackedAssets, CollectionId, ItemId};
|
||||
use xcm::prelude::*;
|
||||
use xcm_builder::{
|
||||
AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith, WithLatestLocationConverter,
|
||||
};
|
||||
use xcm_executor::traits::JustTry;
|
||||
|
||||
/// `Location` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets`
|
||||
pub type AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation, L = Location> =
|
||||
AsPrefixedGeneralIndex<
|
||||
TrustBackedAssetsPalletLocation,
|
||||
AssetIdForTrustBackedAssets,
|
||||
TryConvertInto,
|
||||
L,
|
||||
>;
|
||||
|
||||
/// `Location` vs `CollectionId` converter for `Uniques`
|
||||
pub type CollectionIdForUniquesConvert<UniquesPalletLocation> =
|
||||
AsPrefixedGeneralIndex<UniquesPalletLocation, CollectionId, TryConvertInto>;
|
||||
|
||||
/// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets`
|
||||
pub type TrustBackedAssetsConvertedConcreteId<
|
||||
TrustBackedAssetsPalletLocation,
|
||||
Balance,
|
||||
L = Location,
|
||||
> = MatchedConvertedConcreteId<
|
||||
AssetIdForTrustBackedAssets,
|
||||
Balance,
|
||||
StartsWith<TrustBackedAssetsPalletLocation>,
|
||||
AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation, L>,
|
||||
TryConvertInto,
|
||||
>;
|
||||
|
||||
/// [`MatchedConvertedConcreteId`] converter dedicated for `Uniques`
|
||||
pub type UniquesConvertedConcreteId<UniquesPalletLocation> = MatchedConvertedConcreteId<
|
||||
CollectionId,
|
||||
ItemId,
|
||||
// The asset starts with the uniques pallet. The `CollectionId` of the asset is specified as a
|
||||
// junction within the pallet itself.
|
||||
StartsWith<UniquesPalletLocation>,
|
||||
CollectionIdForUniquesConvert<UniquesPalletLocation>,
|
||||
TryConvertInto,
|
||||
>;
|
||||
|
||||
/// [`MatchedConvertedConcreteId`] converter dedicated for `TrustBackedAssets`,
|
||||
/// it is a similar implementation to `TrustBackedAssetsConvertedConcreteId`,
|
||||
/// but it converts `AssetId` to `xcm::v*::Location` type instead of `AssetIdForTrustBackedAssets =
|
||||
/// u32`
|
||||
pub type TrustBackedAssetsAsLocation<
|
||||
TrustBackedAssetsPalletLocation,
|
||||
Balance,
|
||||
L,
|
||||
LocationConverter = WithLatestLocationConverter<L>,
|
||||
> = MatchedConvertedConcreteId<
|
||||
L,
|
||||
Balance,
|
||||
StartsWith<TrustBackedAssetsPalletLocation>,
|
||||
LocationConverter,
|
||||
TryConvertInto,
|
||||
>;
|
||||
|
||||
/// [`MatchedConvertedConcreteId`] converter dedicated for storing `ForeignAssets` with `AssetId` as
|
||||
/// `Location`.
|
||||
///
|
||||
/// Excludes by default:
|
||||
/// - parent as relay chain
|
||||
/// - all local Locations
|
||||
///
|
||||
/// `AdditionalLocationExclusionFilter` can customize additional excluded Locations
|
||||
pub type ForeignAssetsConvertedConcreteId<
|
||||
AdditionalLocationExclusionFilter,
|
||||
Balance,
|
||||
AssetId,
|
||||
LocationToAssetIdConverter = WithLatestLocationConverter<AssetId>,
|
||||
BalanceConverter = TryConvertInto,
|
||||
> = MatchedConvertedConcreteId<
|
||||
AssetId,
|
||||
Balance,
|
||||
EverythingBut<(
|
||||
// Excludes relay/parent chain currency
|
||||
Equals<ParentLocation>,
|
||||
// Here we rely on fact that something like this works:
|
||||
// assert!(Location::new(1,
|
||||
// [Teyrchain(100)]).starts_with(&Location::parent()));
|
||||
// assert!([Teyrchain(100)].into().starts_with(&Here));
|
||||
StartsWith<LocalLocationPattern>,
|
||||
// Here we can exclude more stuff or leave it as `()`
|
||||
AdditionalLocationExclusionFilter,
|
||||
)>,
|
||||
LocationToAssetIdConverter,
|
||||
BalanceConverter,
|
||||
>;
|
||||
|
||||
/// `Contains<Location>` implementation that matches locations with no parents,
|
||||
/// a `PalletInstance` and an `AccountKey20` junction.
|
||||
pub struct IsLocalAccountKey20;
|
||||
impl Contains<Location> for IsLocalAccountKey20 {
|
||||
fn contains(location: &Location) -> bool {
|
||||
matches!(location.unpack(), (0, [AccountKey20 { .. }]))
|
||||
}
|
||||
}
|
||||
|
||||
/// Fallible converter from a location to a `H160` that matches any location ending with
|
||||
/// an `AccountKey20` junction.
|
||||
pub struct AccountKey20ToH160;
|
||||
impl MaybeEquivalence<Location, H160> for AccountKey20ToH160 {
|
||||
fn convert(location: &Location) -> Option<H160> {
|
||||
match location.unpack() {
|
||||
(0, [AccountKey20 { key, .. }]) => Some((*key).into()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_back(key: &H160) -> Option<Location> {
|
||||
Some(Location::new(0, [AccountKey20 { key: (*key).into(), network: None }]))
|
||||
}
|
||||
}
|
||||
|
||||
/// [`xcm_executor::traits::MatchesFungibles`] implementation that matches
|
||||
/// ERC20 tokens.
|
||||
pub type ERC20Matcher =
|
||||
MatchedConvertedConcreteId<H160, u128, IsLocalAccountKey20, AccountKey20ToH160, JustTry>;
|
||||
|
||||
pub type AssetIdForPoolAssets = u32;
|
||||
|
||||
/// `Location` vs `AssetIdForPoolAssets` converter for `PoolAssets`.
|
||||
pub type AssetIdForPoolAssetsConvert<PoolAssetsPalletLocation, L = Location> =
|
||||
AsPrefixedGeneralIndex<PoolAssetsPalletLocation, AssetIdForPoolAssets, TryConvertInto, L>;
|
||||
/// [`MatchedConvertedConcreteId`] converter dedicated for `PoolAssets`
|
||||
pub type PoolAssetsConvertedConcreteId<PoolAssetsPalletLocation, Balance> =
|
||||
MatchedConvertedConcreteId<
|
||||
AssetIdForPoolAssets,
|
||||
Balance,
|
||||
StartsWith<PoolAssetsPalletLocation>,
|
||||
AssetIdForPoolAssetsConvert<PoolAssetsPalletLocation>,
|
||||
TryConvertInto,
|
||||
>;
|
||||
|
||||
/// Adapter implementation for accessing pools (`pezpallet_asset_conversion`) that uses `AssetKind` as
|
||||
/// a `xcm::v*` which could be different from the `xcm::latest`.
|
||||
pub struct PoolAdapter<Runtime>(PhantomData<Runtime>);
|
||||
impl<
|
||||
Runtime: pezpallet_asset_conversion::Config<PoolId = (L, L), AssetKind = L>,
|
||||
L: TryFrom<Location> + TryInto<Location> + Clone + Decode + EncodeLike + PartialEq,
|
||||
> PoolAdapter<Runtime>
|
||||
{
|
||||
/// Returns a vector of all assets in a pool with `asset`.
|
||||
///
|
||||
/// Should only be used in runtime APIs since it iterates over the whole
|
||||
/// `pezpallet_asset_conversion::Pools` map.
|
||||
///
|
||||
/// It takes in any version of an XCM Location but always returns the latest one.
|
||||
/// This is to allow some margin of migrating the pools when updating the XCM version.
|
||||
///
|
||||
/// An error of type `()` is returned if the version conversion fails for XCM locations.
|
||||
/// This error should be mapped by the caller to a more descriptive one.
|
||||
pub fn get_assets_in_pool_with(asset: Location) -> Result<Vec<AssetId>, ()> {
|
||||
// convert latest to the `L` version.
|
||||
let asset: L = asset.try_into().map_err(|_| ())?;
|
||||
Self::iter_assets_in_pool_with(&asset)
|
||||
.map(|location| {
|
||||
// convert `L` to the latest `AssetId`
|
||||
location.try_into().map_err(|_| ()).map(AssetId)
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
|
||||
/// Provides a current prices. Wrapper over
|
||||
/// `pezpallet_asset_conversion::Pallet::<T>::quote_price_tokens_for_exact_tokens`.
|
||||
///
|
||||
/// An error of type `()` is returned if the version conversion fails for XCM locations.
|
||||
/// This error should be mapped by the caller to a more descriptive one.
|
||||
pub fn quote_price_tokens_for_exact_tokens(
|
||||
asset_1: Location,
|
||||
asset_2: Location,
|
||||
amount: Runtime::Balance,
|
||||
include_fees: bool,
|
||||
) -> Result<Option<Runtime::Balance>, ()> {
|
||||
// Convert latest to the `L` version.
|
||||
let asset_1: L = asset_1.try_into().map_err(|_| ())?;
|
||||
let asset_2: L = asset_2.try_into().map_err(|_| ())?;
|
||||
|
||||
// Quote swap price.
|
||||
Ok(pezpallet_asset_conversion::Pallet::<Runtime>::quote_price_tokens_for_exact_tokens(
|
||||
asset_1,
|
||||
asset_2,
|
||||
amount,
|
||||
include_fees,
|
||||
))
|
||||
}
|
||||
|
||||
/// Helper function for filtering pool.
|
||||
pub fn iter_assets_in_pool_with(asset: &L) -> impl Iterator<Item = L> + '_ {
|
||||
pezpallet_asset_conversion::Pools::<Runtime>::iter_keys().filter_map(|(asset_1, asset_2)| {
|
||||
if asset_1 == *asset {
|
||||
Some(asset_2)
|
||||
} else if asset_2 == *asset {
|
||||
Some(asset_1)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pezsp_runtime::traits::MaybeEquivalence;
|
||||
use xcm_builder::{StartsWithExplicitGlobalConsensus, WithLatestLocationConverter};
|
||||
use xcm_executor::traits::{Error as MatchError, MatchesFungibles};
|
||||
|
||||
#[test]
|
||||
fn asset_id_for_trust_backed_assets_convert_works() {
|
||||
pezframe_support::parameter_types! {
|
||||
pub TrustBackedAssetsPalletLocation: Location = Location::new(5, [PalletInstance(13)]);
|
||||
}
|
||||
let local_asset_id = 123456789 as AssetIdForTrustBackedAssets;
|
||||
let expected_reverse_ref =
|
||||
Location::new(5, [PalletInstance(13), GeneralIndex(local_asset_id.into())]);
|
||||
|
||||
assert_eq!(
|
||||
AssetIdForTrustBackedAssetsConvert::<TrustBackedAssetsPalletLocation>::convert_back(
|
||||
&local_asset_id
|
||||
)
|
||||
.unwrap(),
|
||||
expected_reverse_ref
|
||||
);
|
||||
assert_eq!(
|
||||
AssetIdForTrustBackedAssetsConvert::<TrustBackedAssetsPalletLocation>::convert(
|
||||
&expected_reverse_ref
|
||||
)
|
||||
.unwrap(),
|
||||
local_asset_id
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trust_backed_assets_match_fungibles_works() {
|
||||
pezframe_support::parameter_types! {
|
||||
pub TrustBackedAssetsPalletLocation: Location = Location::new(0, [PalletInstance(13)]);
|
||||
}
|
||||
// set up a converter
|
||||
type TrustBackedAssetsConvert =
|
||||
TrustBackedAssetsConvertedConcreteId<TrustBackedAssetsPalletLocation, u128>;
|
||||
|
||||
let test_data = vec![
|
||||
// missing GeneralIndex
|
||||
(ma_1000(0, [PalletInstance(13)].into()), Err(MatchError::AssetIdConversionFailed)),
|
||||
(
|
||||
ma_1000(0, [PalletInstance(13), GeneralKey { data: [0; 32], length: 32 }].into()),
|
||||
Err(MatchError::AssetIdConversionFailed),
|
||||
),
|
||||
(
|
||||
ma_1000(0, [PalletInstance(13), Teyrchain(1000)].into()),
|
||||
Err(MatchError::AssetIdConversionFailed),
|
||||
),
|
||||
// OK
|
||||
(ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()), Ok((1234, 1000))),
|
||||
(
|
||||
ma_1000(0, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()),
|
||||
Ok((1234, 1000)),
|
||||
),
|
||||
(
|
||||
ma_1000(
|
||||
0,
|
||||
[
|
||||
PalletInstance(13),
|
||||
GeneralIndex(1234),
|
||||
GeneralIndex(2222),
|
||||
GeneralKey { data: [0; 32], length: 32 },
|
||||
]
|
||||
.into(),
|
||||
),
|
||||
Ok((1234, 1000)),
|
||||
),
|
||||
// wrong pallet instance
|
||||
(
|
||||
ma_1000(0, [PalletInstance(77), GeneralIndex(1234)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(0, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
// wrong parent
|
||||
(
|
||||
ma_1000(1, [PalletInstance(13), GeneralIndex(1234)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(1, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(1, [PalletInstance(77), GeneralIndex(1234)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(1, [PalletInstance(77), GeneralIndex(1234), GeneralIndex(2222)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
// wrong parent
|
||||
(
|
||||
ma_1000(2, [PalletInstance(13), GeneralIndex(1234)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(2, [PalletInstance(13), GeneralIndex(1234), GeneralIndex(2222)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
// missing GeneralIndex
|
||||
(ma_1000(0, [PalletInstance(77)].into()), Err(MatchError::AssetNotHandled)),
|
||||
(ma_1000(1, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)),
|
||||
(ma_1000(2, [PalletInstance(13)].into()), Err(MatchError::AssetNotHandled)),
|
||||
];
|
||||
|
||||
for (asset, expected_result) in test_data {
|
||||
assert_eq!(
|
||||
<TrustBackedAssetsConvert as MatchesFungibles<AssetIdForTrustBackedAssets, u128>>::matches_fungibles(&asset.clone().try_into().unwrap()),
|
||||
expected_result, "asset: {:?}", asset);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn foreign_assets_converted_concrete_id_converter_works() {
|
||||
pezframe_support::parameter_types! {
|
||||
pub Teyrchain100Pattern: Location = Location::new(1, [Teyrchain(100)]);
|
||||
pub UniversalLocationNetworkId: NetworkId = NetworkId::ByGenesis([9; 32]);
|
||||
}
|
||||
|
||||
// set up a converter which uses `xcm::v4::Location` under the hood
|
||||
type Convert = ForeignAssetsConvertedConcreteId<
|
||||
(
|
||||
StartsWith<Teyrchain100Pattern>,
|
||||
StartsWithExplicitGlobalConsensus<UniversalLocationNetworkId>,
|
||||
),
|
||||
u128,
|
||||
xcm::v4::Location,
|
||||
WithLatestLocationConverter<xcm::v4::Location>,
|
||||
>;
|
||||
|
||||
let test_data = vec![
|
||||
// excluded as local
|
||||
(ma_1000(0, Here), Err(MatchError::AssetNotHandled)),
|
||||
(ma_1000(0, [Teyrchain(100)].into()), Err(MatchError::AssetNotHandled)),
|
||||
(
|
||||
ma_1000(0, [PalletInstance(13), GeneralIndex(1234)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
// excluded as parent
|
||||
(ma_1000(1, Here), Err(MatchError::AssetNotHandled)),
|
||||
// excluded as additional filter - Teyrchain100Pattern
|
||||
(ma_1000(1, [Teyrchain(100)].into()), Err(MatchError::AssetNotHandled)),
|
||||
(
|
||||
ma_1000(1, [Teyrchain(100), GeneralIndex(1234)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(1, [Teyrchain(100), PalletInstance(13), GeneralIndex(1234)].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
// excluded as additional filter - StartsWithExplicitGlobalConsensus
|
||||
(
|
||||
ma_1000(1, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([9; 32]))].into()),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
(
|
||||
ma_1000(
|
||||
2,
|
||||
[
|
||||
GlobalConsensus(NetworkId::ByGenesis([9; 32])),
|
||||
Teyrchain(200),
|
||||
GeneralIndex(1234),
|
||||
]
|
||||
.into(),
|
||||
),
|
||||
Err(MatchError::AssetNotHandled),
|
||||
),
|
||||
// ok
|
||||
(
|
||||
ma_1000(1, [Teyrchain(200)].into()),
|
||||
Ok((xcm::v4::Location::new(1, [xcm::v4::Junction::Teyrchain(200)]), 1000)),
|
||||
),
|
||||
(
|
||||
ma_1000(2, [Teyrchain(200)].into()),
|
||||
Ok((xcm::v4::Location::new(2, [xcm::v4::Junction::Teyrchain(200)]), 1000)),
|
||||
),
|
||||
(
|
||||
ma_1000(1, [Teyrchain(200), GeneralIndex(1234)].into()),
|
||||
Ok((
|
||||
xcm::v4::Location::new(
|
||||
1,
|
||||
[xcm::v4::Junction::Teyrchain(200), xcm::v4::Junction::GeneralIndex(1234)],
|
||||
),
|
||||
1000,
|
||||
)),
|
||||
),
|
||||
(
|
||||
ma_1000(2, [Teyrchain(200), GeneralIndex(1234)].into()),
|
||||
Ok((
|
||||
xcm::v4::Location::new(
|
||||
2,
|
||||
[xcm::v4::Junction::Teyrchain(200), xcm::v4::Junction::GeneralIndex(1234)],
|
||||
),
|
||||
1000,
|
||||
)),
|
||||
),
|
||||
(
|
||||
ma_1000(2, [GlobalConsensus(NetworkId::ByGenesis([7; 32]))].into()),
|
||||
Ok((
|
||||
xcm::v4::Location::new(
|
||||
2,
|
||||
[xcm::v4::Junction::GlobalConsensus(xcm::v4::NetworkId::ByGenesis(
|
||||
[7; 32],
|
||||
))],
|
||||
),
|
||||
1000,
|
||||
)),
|
||||
),
|
||||
(
|
||||
ma_1000(
|
||||
2,
|
||||
[
|
||||
GlobalConsensus(NetworkId::ByGenesis([7; 32])),
|
||||
Teyrchain(200),
|
||||
GeneralIndex(1234),
|
||||
]
|
||||
.into(),
|
||||
),
|
||||
Ok((
|
||||
xcm::v4::Location::new(
|
||||
2,
|
||||
[
|
||||
xcm::v4::Junction::GlobalConsensus(xcm::v4::NetworkId::ByGenesis(
|
||||
[7; 32],
|
||||
)),
|
||||
xcm::v4::Junction::Teyrchain(200),
|
||||
xcm::v4::Junction::GeneralIndex(1234),
|
||||
],
|
||||
),
|
||||
1000,
|
||||
)),
|
||||
),
|
||||
];
|
||||
|
||||
for (asset, expected_result) in test_data {
|
||||
assert_eq!(
|
||||
<Convert as MatchesFungibles<xcm::v4::Location, u128>>::matches_fungibles(
|
||||
&asset.clone().try_into().unwrap()
|
||||
),
|
||||
expected_result,
|
||||
"asset: {:?}",
|
||||
asset
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Create Asset
|
||||
fn ma_1000(parents: u8, interior: Junctions) -> Asset {
|
||||
(Location::new(parents, interior), 1000).into()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user