mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 22:11:02 +00:00
* Assets balances * Update docs * AssetsApi with MultiLocation as preparation for multi pallet_assets instances (#2187) * AssetsApi with MultiLocation for Westmint + assets-common * AssetsApi with MultiLocation for Statemine/t * typo * typo for check-docs job * WIP: AssetsApi return MultiAsset instead of (MultiLocation, Balance) * WIP: assets_api + conversion refactor * WIP: assets_api + conversion refactor * Finished asset runtimes * Refactor AssetsApi to FungiblesApi * Refactor * Fix check-rust-docs * Removed todo * Fix check-rust-doc * Update parachains/runtimes/assets/common/Cargo.toml Co-authored-by: Bastian Köcher <git@kchr.de> * update lockfile for {"substrate", "polkadot"} --------- Co-authored-by: Branislav Kontur <bkontur@gmail.com> Co-authored-by: parity-processbot <> Co-authored-by: Bastian Köcher <git@kchr.de>
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
[package]
|
||||
name = "assets-common"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2021"
|
||||
description = "Assets common utilities"
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
|
||||
|
||||
# Substrate
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
# Polkadot
|
||||
xcm = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-builder = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = false, branch = "master" }
|
||||
|
||||
# Cumulus
|
||||
parachains-common = { path = "../../../common", default-features = false }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = [ "std" ]
|
||||
std = [
|
||||
"codec/std",
|
||||
"frame-support/std",
|
||||
"parachains-common/std",
|
||||
"sp-api/std",
|
||||
"sp-std/std",
|
||||
"xcm/std",
|
||||
"xcm-builder/std",
|
||||
"xcm-executor/std",
|
||||
]
|
||||
@@ -0,0 +1,136 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// Copyright (C) 2018-2022 Parity Technologies (UK) Ltd.
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
||||
|
||||
// This program 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.
|
||||
|
||||
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
//! Runtime API definition for assets.
|
||||
|
||||
use crate::runtime_api::FungiblesAccessError;
|
||||
use sp_std::{borrow::Borrow, vec::Vec};
|
||||
use xcm::latest::{MultiAsset, MultiLocation};
|
||||
use xcm_builder::ConvertedConcreteId;
|
||||
use xcm_executor::traits::{Convert, MatchesFungibles};
|
||||
|
||||
/// Converting any [`(AssetId, Balance)`] to [`MultiAsset`]
|
||||
pub trait MultiAssetConverter<AssetId, Balance, ConvertAssetId, ConvertBalance>:
|
||||
MatchesFungibles<AssetId, Balance>
|
||||
where
|
||||
AssetId: Clone,
|
||||
Balance: Clone,
|
||||
ConvertAssetId: Convert<MultiLocation, AssetId>,
|
||||
ConvertBalance: Convert<u128, Balance>,
|
||||
{
|
||||
fn convert_ref(
|
||||
value: impl Borrow<(AssetId, Balance)>,
|
||||
) -> Result<MultiAsset, FungiblesAccessError>;
|
||||
}
|
||||
|
||||
impl<
|
||||
AssetId: Clone,
|
||||
Balance: Clone,
|
||||
ConvertAssetId: Convert<MultiLocation, AssetId>,
|
||||
ConvertBalance: Convert<u128, Balance>,
|
||||
> MultiAssetConverter<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
for ConvertedConcreteId<AssetId, Balance, ConvertAssetId, ConvertBalance>
|
||||
{
|
||||
fn convert_ref(
|
||||
value: impl Borrow<(AssetId, Balance)>,
|
||||
) -> Result<MultiAsset, FungiblesAccessError> {
|
||||
let (asset_id, balance) = value.borrow();
|
||||
match ConvertAssetId::reverse_ref(asset_id) {
|
||||
Ok(asset_id_as_multilocation) => match ConvertBalance::reverse_ref(balance) {
|
||||
Ok(amount) => Ok((asset_id_as_multilocation, amount).into()),
|
||||
Err(_) => Err(FungiblesAccessError::AmountToBalanceConversionFailed),
|
||||
},
|
||||
Err(_) => Err(FungiblesAccessError::AssetIdConversionFailed),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to convert collections with [`(AssetId, Balance)`] to [`MultiAsset`]
|
||||
pub fn convert<'a, AssetId, Balance, ConvertAssetId, ConvertBalance, Converter>(
|
||||
items: impl Iterator<Item = &'a (AssetId, Balance)>,
|
||||
) -> Result<Vec<MultiAsset>, FungiblesAccessError>
|
||||
where
|
||||
AssetId: Clone + 'a,
|
||||
Balance: Clone + 'a,
|
||||
ConvertAssetId: Convert<MultiLocation, AssetId>,
|
||||
ConvertBalance: Convert<u128, Balance>,
|
||||
Converter: MultiAssetConverter<AssetId, Balance, ConvertAssetId, ConvertBalance>,
|
||||
{
|
||||
items.map(Converter::convert_ref).collect()
|
||||
}
|
||||
|
||||
/// Helper function to convert `Balance` with MultiLocation` to `MultiAsset`
|
||||
pub fn convert_balance<
|
||||
T: frame_support::pallet_prelude::Get<MultiLocation>,
|
||||
Balance: TryInto<u128>,
|
||||
>(
|
||||
balance: Balance,
|
||||
) -> Result<MultiAsset, FungiblesAccessError> {
|
||||
match balance.try_into() {
|
||||
Ok(balance) => Ok((T::get(), balance).into()),
|
||||
Err(_) => Err(FungiblesAccessError::AmountToBalanceConversionFailed),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_executor::traits::{Identity, JustTry};
|
||||
|
||||
type Converter = ConvertedConcreteId<MultiLocation, u64, Identity, JustTry>;
|
||||
|
||||
#[test]
|
||||
fn converted_concrete_id_fungible_multi_asset_conversion_roundtrip_works() {
|
||||
let location = MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))));
|
||||
let amount = 123456_u64;
|
||||
let expected_multi_asset = MultiAsset {
|
||||
id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))),
|
||||
fun: Fungible(123456_u128),
|
||||
};
|
||||
|
||||
assert_eq!(
|
||||
Converter::matches_fungibles(&expected_multi_asset).map_err(|_| ()),
|
||||
Ok((location, amount))
|
||||
);
|
||||
|
||||
assert_eq!(Converter::convert_ref((location, amount)), Ok(expected_multi_asset));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn converted_concrete_id_fungible_multi_asset_conversion_collection_works() {
|
||||
let data = vec![
|
||||
(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32])))), 123456_u64),
|
||||
(MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32])))), 654321_u64),
|
||||
];
|
||||
|
||||
let expected_data = vec![
|
||||
MultiAsset {
|
||||
id: Concrete(MultiLocation::new(0, X1(GlobalConsensus(ByGenesis([0; 32]))))),
|
||||
fun: Fungible(123456_u128),
|
||||
},
|
||||
MultiAsset {
|
||||
id: Concrete(MultiLocation::new(1, X1(GlobalConsensus(ByGenesis([1; 32]))))),
|
||||
fun: Fungible(654321_u128),
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!(convert::<_, _, _, _, Converter>(data.iter()), Ok(expected_data));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// Copyright (C) 2023 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)]
|
||||
|
||||
pub mod fungible_conversion;
|
||||
pub mod runtime_api;
|
||||
|
||||
use parachains_common::AssetIdForTrustBackedAssets;
|
||||
use xcm_builder::{AsPrefixedGeneralIndex, ConvertedConcreteId};
|
||||
use xcm_executor::traits::JustTry;
|
||||
|
||||
/// `MultiLocation` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets`
|
||||
pub type AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation> =
|
||||
AsPrefixedGeneralIndex<TrustBackedAssetsPalletLocation, AssetIdForTrustBackedAssets, JustTry>;
|
||||
|
||||
/// [`ConvertedConcreteId`] converter dedicated for `TrustBackedAssets`
|
||||
pub type TrustBackedAssetsConvertedConcreteId<TrustBackedAssetsPalletLocation, Balance> =
|
||||
ConvertedConcreteId<
|
||||
AssetIdForTrustBackedAssets,
|
||||
Balance,
|
||||
AssetIdForTrustBackedAssetsConvert<TrustBackedAssetsPalletLocation>,
|
||||
JustTry,
|
||||
>;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
use xcm::latest::prelude::*;
|
||||
use xcm_executor::traits::Convert;
|
||||
|
||||
frame_support::parameter_types! {
|
||||
pub TrustBackedAssetsPalletLocation: MultiLocation = MultiLocation::new(5, X1(PalletInstance(13)));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn asset_id_for_trust_backed_assets_convert_works() {
|
||||
let local_asset_id = 123456789 as AssetIdForTrustBackedAssets;
|
||||
let expected_reverse_ref =
|
||||
MultiLocation::new(5, X2(PalletInstance(13), GeneralIndex(local_asset_id.into())));
|
||||
|
||||
assert_eq!(
|
||||
AssetIdForTrustBackedAssetsConvert::<TrustBackedAssetsPalletLocation>::reverse_ref(
|
||||
local_asset_id
|
||||
)
|
||||
.unwrap(),
|
||||
expected_reverse_ref
|
||||
);
|
||||
assert_eq!(
|
||||
AssetIdForTrustBackedAssetsConvert::<TrustBackedAssetsPalletLocation>::convert_ref(
|
||||
expected_reverse_ref
|
||||
)
|
||||
.unwrap(),
|
||||
local_asset_id
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2023 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.
|
||||
|
||||
//! Runtime API definition for fungibles.
|
||||
|
||||
use codec::{Codec, Decode, Encode};
|
||||
use frame_support::RuntimeDebug;
|
||||
use sp_std::vec::Vec;
|
||||
use xcm::latest::MultiAsset;
|
||||
|
||||
/// The possible errors that can happen querying the storage of assets.
|
||||
#[derive(Eq, PartialEq, Encode, Decode, RuntimeDebug)]
|
||||
pub enum FungiblesAccessError {
|
||||
/// `MultiLocation` to `AssetId`/`ClassId` conversion failed.
|
||||
AssetIdConversionFailed,
|
||||
/// `u128` amount to currency `Balance` conversion failed.
|
||||
AmountToBalanceConversionFailed,
|
||||
}
|
||||
|
||||
sp_api::decl_runtime_apis! {
|
||||
/// The API for querying account's balances from runtime.
|
||||
pub trait FungiblesApi<AccountId>
|
||||
where
|
||||
AccountId: Codec,
|
||||
{
|
||||
/// Returns the list of all [`MultiAsset`] that an `AccountId` has.
|
||||
fn query_account_balances(account: AccountId) -> Result<Vec<MultiAsset>, FungiblesAccessError>;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user