diff --git a/substrate/bin/node/runtime/src/assets_api.rs b/substrate/bin/node/runtime/src/assets_api.rs new file mode 100644 index 000000000000..cf1a663d7030 --- /dev/null +++ b/substrate/bin/node/runtime/src/assets_api.rs @@ -0,0 +1,34 @@ +// 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 . + +//! Runtime API definition for assets. + +use codec::Codec; +use sp_std::vec::Vec; + +sp_api::decl_runtime_apis! { + pub trait AssetsApi + where + AccountId: Codec, + AssetBalance: Codec, + AssetId: Codec, + { + /// Returns the list of `AssetId`s and corresponding balance that an `AccountId` has. + fn account_balances(account: AccountId) -> Vec<(AssetId, AssetBalance)>; + } +} diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs index f8589036f785..9b317926a5a9 100644 --- a/substrate/bin/node/runtime/src/lib.rs +++ b/substrate/bin/node/runtime/src/lib.rs @@ -105,6 +105,9 @@ use sp_runtime::generic::Era; /// Generated voter bag information. mod voter_bags; +/// Runtime API definition for assets. +pub mod assets_api; + // Make the WASM binary available. #[cfg(feature = "std")] include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs")); @@ -2072,6 +2075,18 @@ impl_runtime_apis! { } } + impl assets_api::AssetsApi< + Block, + AccountId, + Balance, + u32, + > for Runtime + { + fn account_balances(account: AccountId) -> Vec<(u32, Balance)> { + Assets::account_balances(account) + } + } + impl pallet_contracts::ContractsApi for Runtime { fn call( diff --git a/substrate/frame/assets/src/functions.rs b/substrate/frame/assets/src/functions.rs index f970ce6cf564..f6e027472f15 100644 --- a/substrate/frame/assets/src/functions.rs +++ b/substrate/frame/assets/src/functions.rs @@ -924,4 +924,11 @@ impl, I: 'static> Pallet { Ok(()) }) } + + /// Returns all the non-zero balances for all assets of the given `account`. + pub fn account_balances(account: T::AccountId) -> Vec<(T::AssetId, T::Balance)> { + Asset::::iter_keys() + .filter_map(|id| Self::maybe_balance(id, account.clone()).map(|balance| (id, balance))) + .collect::>() + } } diff --git a/substrate/frame/assets/src/tests.rs b/substrate/frame/assets/src/tests.rs index e76e989ef893..e0f612e5cd78 100644 --- a/substrate/frame/assets/src/tests.rs +++ b/substrate/frame/assets/src/tests.rs @@ -37,11 +37,14 @@ fn asset_ids() -> Vec { fn basic_minting_should_work() { new_test_ext().execute_with(|| { assert_ok!(Assets::force_create(RuntimeOrigin::root(), 0, 1, true, 1)); + assert_ok!(Assets::force_create(RuntimeOrigin::root(), 1, 1, true, 1)); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 1, 100)); assert_eq!(Assets::balance(0, 1), 100); assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 0, 2, 100)); assert_eq!(Assets::balance(0, 2), 100); - assert_eq!(asset_ids(), vec![0, 999]); + assert_eq!(asset_ids(), vec![0, 1, 999]); + assert_ok!(Assets::mint(RuntimeOrigin::signed(1), 1, 1, 100)); + assert_eq!(Assets::account_balances(1), vec![(0, 100), (999, 100), (1, 100)]); }); }