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)]);
});
}