mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-11 18:51:12 +00:00
Nfts attribute read interface (#13349)
* feat: add custom and system attributes to Inspect * feat: add nfts runtime api * fix: pass std feature to runtime api * fix: api copyright Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com> --------- Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
Generated
+11
@@ -3558,6 +3558,7 @@ dependencies = [
|
||||
"pallet-mmr",
|
||||
"pallet-multisig",
|
||||
"pallet-nfts",
|
||||
"pallet-nfts-runtime-api",
|
||||
"pallet-nis",
|
||||
"pallet-nomination-pools",
|
||||
"pallet-nomination-pools-benchmarking",
|
||||
@@ -6038,6 +6039,16 @@ dependencies = [
|
||||
"sp-std",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-nfts-runtime-api"
|
||||
version = "4.0.0-dev"
|
||||
dependencies = [
|
||||
"frame-support",
|
||||
"pallet-nfts",
|
||||
"parity-scale-codec",
|
||||
"sp-api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pallet-nicks"
|
||||
version = "4.0.0-dev"
|
||||
|
||||
@@ -122,6 +122,7 @@ members = [
|
||||
"frame/proxy",
|
||||
"frame/message-queue",
|
||||
"frame/nfts",
|
||||
"frame/nfts/runtime-api",
|
||||
"frame/nomination-pools",
|
||||
"frame/nomination-pools/fuzzer",
|
||||
"frame/nomination-pools/benchmarking",
|
||||
|
||||
@@ -79,6 +79,7 @@ pallet-message-queue = { version = "7.0.0-dev", default-features = false, path =
|
||||
pallet-mmr = { version = "4.0.0-dev", default-features = false, path = "../../../frame/merkle-mountain-range" }
|
||||
pallet-multisig = { version = "4.0.0-dev", default-features = false, path = "../../../frame/multisig" }
|
||||
pallet-nfts = { version = "4.0.0-dev", default-features = false, path = "../../../frame/nfts" }
|
||||
pallet-nfts-runtime-api = { version = "4.0.0-dev", default-features = false, path = "../../../frame/nfts/runtime-api" }
|
||||
pallet-nomination-pools = { version = "1.0.0", default-features = false, path = "../../../frame/nomination-pools"}
|
||||
pallet-nomination-pools-benchmarking = { version = "1.0.0", default-features = false, optional = true, path = "../../../frame/nomination-pools/benchmarking" }
|
||||
pallet-nomination-pools-runtime-api = { version = "1.0.0-dev", default-features = false, path = "../../../frame/nomination-pools/runtime-api" }
|
||||
@@ -203,6 +204,7 @@ std = [
|
||||
"pallet-recovery/std",
|
||||
"pallet-uniques/std",
|
||||
"pallet-nfts/std",
|
||||
"pallet-nfts-runtime-api/std",
|
||||
"pallet-vesting/std",
|
||||
"log/std",
|
||||
"frame-try-runtime?/std",
|
||||
|
||||
@@ -33,10 +33,10 @@ use frame_support::{
|
||||
pallet_prelude::Get,
|
||||
parameter_types,
|
||||
traits::{
|
||||
fungible::ItemOf, AsEnsureOriginWithArg, ConstBool, ConstU128, ConstU16, ConstU32,
|
||||
Currency, EitherOfDiverse, EqualPrivilegeOnly, Everything, Imbalance, InstanceFilter,
|
||||
KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced, U128CurrencyToVote,
|
||||
WithdrawReasons,
|
||||
fungible::ItemOf, tokens::nonfungibles_v2::Inspect, AsEnsureOriginWithArg, ConstBool,
|
||||
ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse, EqualPrivilegeOnly, Everything,
|
||||
Imbalance, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced,
|
||||
U128CurrencyToVote, WithdrawReasons,
|
||||
},
|
||||
weights::{
|
||||
constants::{
|
||||
@@ -2187,6 +2187,50 @@ impl_runtime_apis! {
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_nfts_runtime_api::NftsApi<Block, AccountId, u32, u32> for Runtime {
|
||||
fn owner(collection: u32, item: u32) -> Option<AccountId> {
|
||||
<Nfts as Inspect<AccountId>>::owner(&collection, &item)
|
||||
}
|
||||
|
||||
fn collection_owner(collection: u32) -> Option<AccountId> {
|
||||
<Nfts as Inspect<AccountId>>::collection_owner(&collection)
|
||||
}
|
||||
|
||||
fn attribute(
|
||||
collection: u32,
|
||||
item: u32,
|
||||
key: Vec<u8>,
|
||||
) -> Option<Vec<u8>> {
|
||||
<Nfts as Inspect<AccountId>>::attribute(&collection, &item, &key)
|
||||
}
|
||||
|
||||
fn custom_attribute(
|
||||
account: AccountId,
|
||||
collection: u32,
|
||||
item: u32,
|
||||
key: Vec<u8>,
|
||||
) -> Option<Vec<u8>> {
|
||||
<Nfts as Inspect<AccountId>>::custom_attribute(
|
||||
&account,
|
||||
&collection,
|
||||
&item,
|
||||
&key,
|
||||
)
|
||||
}
|
||||
|
||||
fn system_attribute(
|
||||
collection: u32,
|
||||
item: u32,
|
||||
key: Vec<u8>,
|
||||
) -> Option<Vec<u8>> {
|
||||
<Nfts as Inspect<AccountId>>::system_attribute(&collection, &item, &key)
|
||||
}
|
||||
|
||||
fn collection_attribute(collection: u32, key: Vec<u8>) -> Option<Vec<u8>> {
|
||||
<Nfts as Inspect<AccountId>>::collection_attribute(&collection, &key)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_mmr::primitives::MmrApi<
|
||||
Block,
|
||||
mmr::Hash,
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "pallet-nfts-runtime-api"
|
||||
version = "4.0.0-dev"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2021"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://substrate.io"
|
||||
repository = "https://github.com/paritytech/substrate/"
|
||||
description = "Runtime API for the FRAME NFTs pallet."
|
||||
readme = "README.md"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] }
|
||||
frame-support = { version = "4.0.0-dev", default-features = false, path = "../../support" }
|
||||
pallet-nfts = { version = "4.0.0-dev", default-features = false, path = "../../nfts" }
|
||||
sp-api = { version = "4.0.0-dev", default-features = false, path = "../../../primitives/api" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"codec/std",
|
||||
"frame-support/std",
|
||||
"pallet-nfts/std",
|
||||
"sp-api/std",
|
||||
]
|
||||
@@ -0,0 +1,3 @@
|
||||
RPC runtime API for the FRAME NFTs pallet.
|
||||
|
||||
License: Apache-2.0
|
||||
@@ -0,0 +1,57 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// 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 the FRAME NFTs pallet.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::dispatch::Vec;
|
||||
|
||||
sp_api::decl_runtime_apis! {
|
||||
pub trait NftsApi<AccountId, CollectionId, ItemId>
|
||||
where
|
||||
AccountId: Encode + Decode,
|
||||
CollectionId: Encode,
|
||||
ItemId: Encode,
|
||||
{
|
||||
fn owner(collection: CollectionId, item: ItemId) -> Option<AccountId>;
|
||||
|
||||
fn collection_owner(collection: CollectionId) -> Option<AccountId>;
|
||||
|
||||
fn attribute(
|
||||
collection: CollectionId,
|
||||
item: ItemId,
|
||||
key: Vec<u8>,
|
||||
) -> Option<Vec<u8>>;
|
||||
|
||||
fn custom_attribute(
|
||||
account: AccountId,
|
||||
collection: CollectionId,
|
||||
item: ItemId,
|
||||
key: Vec<u8>,
|
||||
) -> Option<Vec<u8>>;
|
||||
|
||||
fn system_attribute(
|
||||
collection: CollectionId,
|
||||
item: ItemId,
|
||||
key: Vec<u8>,
|
||||
) -> Option<Vec<u8>>;
|
||||
|
||||
fn collection_attribute(collection: CollectionId, key: Vec<u8>) -> Option<Vec<u8>>;
|
||||
}
|
||||
}
|
||||
@@ -50,18 +50,48 @@ impl<T: Config<I>, I: 'static> Inspect<<T as SystemConfig>::AccountId> for Palle
|
||||
fn attribute(
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<<T as SystemConfig>::AccountId>,
|
||||
key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
if key.is_empty() {
|
||||
// We make the empty key map to the item metadata value.
|
||||
ItemMetadataOf::<T, I>::get(collection, item).map(|m| m.data.into())
|
||||
} else {
|
||||
let namespace = AttributeNamespace::CollectionOwner;
|
||||
let key = BoundedSlice::<_, _>::try_from(key).ok()?;
|
||||
Attribute::<T, I>::get((collection, Some(item), namespace, key)).map(|a| a.0.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the custom attribute value of `item` of `collection` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn custom_attribute(
|
||||
account: &T::AccountId,
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
let namespace = Account::<T, I>::get((account, collection, item))
|
||||
.map(|_| AttributeNamespace::ItemOwner)
|
||||
.unwrap_or_else(|| AttributeNamespace::Account(account.clone()));
|
||||
|
||||
let key = BoundedSlice::<_, _>::try_from(key).ok()?;
|
||||
Attribute::<T, I>::get((collection, Some(item), namespace, key)).map(|a| a.0.into())
|
||||
}
|
||||
|
||||
/// Returns the system attribute value of `item` of `collection` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn system_attribute(
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
let namespace = AttributeNamespace::Pallet;
|
||||
let key = BoundedSlice::<_, _>::try_from(key).ok()?;
|
||||
Attribute::<T, I>::get((collection, Some(item), namespace, key)).map(|a| a.0.into())
|
||||
}
|
||||
|
||||
/// Returns the attribute value of `item` of `collection` corresponding to `key`.
|
||||
///
|
||||
/// When `key` is empty, we return the item metadata value.
|
||||
|
||||
@@ -25,10 +25,7 @@
|
||||
//! use.
|
||||
|
||||
use super::nonfungibles_v2 as nonfungibles;
|
||||
use crate::{
|
||||
dispatch::DispatchResult,
|
||||
traits::{tokens::misc::AttributeNamespace, Get},
|
||||
};
|
||||
use crate::{dispatch::DispatchResult, traits::Get};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_runtime::TokenError;
|
||||
use sp_std::prelude::*;
|
||||
@@ -45,23 +42,53 @@ pub trait Inspect<AccountId> {
|
||||
/// Returns the attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn attribute(
|
||||
fn attribute(_item: &Self::ItemId, _key: &[u8]) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the custom attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn custom_attribute(
|
||||
_account: &AccountId,
|
||||
_item: &Self::ItemId,
|
||||
_namespace: &AttributeNamespace<AccountId>,
|
||||
_key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the system attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn system_attribute(_item: &Self::ItemId, _key: &[u8]) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this just attempts to use `attribute`.
|
||||
fn typed_attribute<K: Encode, V: Decode>(
|
||||
fn typed_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
|
||||
key.using_encoded(|d| Self::attribute(item, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed custom attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this just attempts to use `custom_attribute`.
|
||||
fn typed_custom_attribute<K: Encode, V: Decode>(
|
||||
account: &AccountId,
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
key.using_encoded(|d| Self::attribute(item, namespace, d))
|
||||
key.using_encoded(|d| Self::custom_attribute(account, item, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed system attribute value of `item` corresponding to `key`.
|
||||
///
|
||||
/// By default this just attempts to use `system_attribute`.
|
||||
fn typed_system_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
|
||||
key.using_encoded(|d| Self::system_attribute(item, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
@@ -167,19 +194,32 @@ impl<
|
||||
fn owner(item: &Self::ItemId) -> Option<AccountId> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::owner(&A::get(), item)
|
||||
}
|
||||
fn attribute(
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::attribute(&A::get(), item, namespace, key)
|
||||
fn attribute(item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::attribute(&A::get(), item, key)
|
||||
}
|
||||
fn typed_attribute<K: Encode, V: Decode>(
|
||||
fn custom_attribute(account: &AccountId, item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::custom_attribute(account, &A::get(), item, key)
|
||||
}
|
||||
fn system_attribute(item: &Self::ItemId, key: &[u8]) -> Option<Vec<u8>> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::system_attribute(&A::get(), item, key)
|
||||
}
|
||||
fn typed_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::typed_attribute(&A::get(), item, key)
|
||||
}
|
||||
fn typed_custom_attribute<K: Encode, V: Decode>(
|
||||
account: &AccountId,
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::typed_attribute(&A::get(), item, namespace, key)
|
||||
<F as nonfungibles::Inspect<AccountId>>::typed_custom_attribute(
|
||||
account,
|
||||
&A::get(),
|
||||
item,
|
||||
key,
|
||||
)
|
||||
}
|
||||
fn typed_system_attribute<K: Encode, V: Decode>(item: &Self::ItemId, key: &K) -> Option<V> {
|
||||
<F as nonfungibles::Inspect<AccountId>>::typed_system_attribute(&A::get(), item, key)
|
||||
}
|
||||
fn can_transfer(item: &Self::ItemId) -> bool {
|
||||
<F as nonfungibles::Inspect<AccountId>>::can_transfer(&A::get(), item)
|
||||
|
||||
@@ -27,10 +27,7 @@
|
||||
//! Implementations of these traits may be converted to implementations of corresponding
|
||||
//! `nonfungible` traits by using the `nonfungible::ItemOf` type adapter.
|
||||
|
||||
use crate::{
|
||||
dispatch::{DispatchError, DispatchResult},
|
||||
traits::tokens::misc::AttributeNamespace,
|
||||
};
|
||||
use crate::dispatch::{DispatchError, DispatchResult};
|
||||
use codec::{Decode, Encode};
|
||||
use sp_runtime::TokenError;
|
||||
use sp_std::prelude::*;
|
||||
@@ -61,7 +58,29 @@ pub trait Inspect<AccountId> {
|
||||
fn attribute(
|
||||
_collection: &Self::CollectionId,
|
||||
_item: &Self::ItemId,
|
||||
_namespace: &AttributeNamespace<AccountId>,
|
||||
_key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the custom attribute value of `item` of `collection` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn custom_attribute(
|
||||
_account: &AccountId,
|
||||
_collection: &Self::CollectionId,
|
||||
_item: &Self::ItemId,
|
||||
_key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
None
|
||||
}
|
||||
|
||||
/// Returns the system attribute value of `item` of `collection` corresponding to `key`.
|
||||
///
|
||||
/// By default this is `None`; no attributes are defined.
|
||||
fn system_attribute(
|
||||
_collection: &Self::CollectionId,
|
||||
_item: &Self::ItemId,
|
||||
_key: &[u8],
|
||||
) -> Option<Vec<u8>> {
|
||||
None
|
||||
@@ -74,10 +93,36 @@ pub trait Inspect<AccountId> {
|
||||
fn typed_attribute<K: Encode, V: Decode>(
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
namespace: &AttributeNamespace<AccountId>,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
key.using_encoded(|d| Self::attribute(collection, item, namespace, d))
|
||||
key.using_encoded(|d| Self::attribute(collection, item, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed custom attribute value of `item` of `collection` corresponding to
|
||||
/// `key`.
|
||||
///
|
||||
/// By default this just attempts to use `custom_attribute`.
|
||||
fn typed_custom_attribute<K: Encode, V: Decode>(
|
||||
account: &AccountId,
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
key.using_encoded(|d| Self::custom_attribute(account, collection, item, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
/// Returns the strongly-typed system attribute value of `item` of `collection` corresponding to
|
||||
/// `key`.
|
||||
///
|
||||
/// By default this just attempts to use `system_attribute`.
|
||||
fn typed_system_attribute<K: Encode, V: Decode>(
|
||||
collection: &Self::CollectionId,
|
||||
item: &Self::ItemId,
|
||||
key: &K,
|
||||
) -> Option<V> {
|
||||
key.using_encoded(|d| Self::system_attribute(collection, item, d))
|
||||
.and_then(|v| V::decode(&mut &v[..]).ok())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user