git.delta.rocks / unique-network / refs/commits / 9bbb15434bf2

difftreelog

source

client/rpc/src/lib.rs7.5 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617// Original License18use std::sync::Arc;1920use codec::Decode;21use jsonrpc_core::{Error as RpcError, ErrorCode, Result};22use jsonrpc_derive::rpc;23use up_data_structs::{Collection, CollectionId, CollectionStats, CollectionLimits, TokenId};24use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};25use sp_blockchain::HeaderBackend;26use up_rpc::UniqueApi as UniqueRuntimeApi;2728#[rpc]29pub trait UniqueApi<BlockHash, CrossAccountId, AccountId> {30	#[rpc(name = "unique_accountTokens")]31	fn account_tokens(32		&self,33		collection: CollectionId,34		account: CrossAccountId,35		at: Option<BlockHash>,36	) -> Result<Vec<TokenId>>;37	#[rpc(name = "unique_tokenExists")]38	fn token_exists(39		&self,40		collection: CollectionId,41		token: TokenId,42		at: Option<BlockHash>,43	) -> Result<bool>;4445	#[rpc(name = "unique_tokenOwner")]46	fn token_owner(47		&self,48		collection: CollectionId,49		token: TokenId,50		at: Option<BlockHash>,51	) -> Result<Option<CrossAccountId>>;52	#[rpc(name = "unique_constMetadata")]53	fn const_metadata(54		&self,55		collection: CollectionId,56		token: TokenId,57		at: Option<BlockHash>,58	) -> Result<Vec<u8>>;59	#[rpc(name = "unique_variableMetadata")]60	fn variable_metadata(61		&self,62		collection: CollectionId,63		token: TokenId,64		at: Option<BlockHash>,65	) -> Result<Vec<u8>>;6667	#[rpc(name = "unique_collectionTokens")]68	fn collection_tokens(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<u32>;69	#[rpc(name = "unique_accountBalance")]70	fn account_balance(71		&self,72		collection: CollectionId,73		account: CrossAccountId,74		at: Option<BlockHash>,75	) -> Result<u32>;76	#[rpc(name = "unique_balance")]77	fn balance(78		&self,79		collection: CollectionId,80		account: CrossAccountId,81		token: TokenId,82		at: Option<BlockHash>,83	) -> Result<String>;84	#[rpc(name = "unique_allowance")]85	fn allowance(86		&self,87		collection: CollectionId,88		sender: CrossAccountId,89		spender: CrossAccountId,90		token: TokenId,91		at: Option<BlockHash>,92	) -> Result<String>;9394	#[rpc(name = "unique_adminlist")]95	fn adminlist(96		&self,97		collection: CollectionId,98		at: Option<BlockHash>,99	) -> Result<Vec<CrossAccountId>>;100	#[rpc(name = "unique_allowlist")]101	fn allowlist(102		&self,103		collection: CollectionId,104		at: Option<BlockHash>,105	) -> Result<Vec<CrossAccountId>>;106	#[rpc(name = "unique_allowed")]107	fn allowed(108		&self,109		collection: CollectionId,110		user: CrossAccountId,111		at: Option<BlockHash>,112	) -> Result<bool>;113	#[rpc(name = "unique_lastTokenId")]114	fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;115	#[rpc(name = "unique_collectionById")]116	fn collection_by_id(117		&self,118		collection: CollectionId,119		at: Option<BlockHash>,120	) -> Result<Option<Collection<AccountId>>>;121	#[rpc(name = "unique_collectionStats")]122	fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;123124	#[rpc(name = "unique_nextSponsored")]125	fn next_sponsored(126		&self,127		collection: CollectionId,128		account: CrossAccountId,129		token: TokenId,130		at: Option<BlockHash>,131	) -> Result<Option<u64>>;132	#[rpc(name = "unique_effectiveCollectionLimits")]133	fn effective_collection_limits(134		&self,135		collection_id: CollectionId,136		at: Option<BlockHash>,137	) -> Result<Option<CollectionLimits>>;138}139140pub struct Unique<C, P> {141	client: Arc<C>,142	_marker: std::marker::PhantomData<P>,143}144145impl<C, P> Unique<C, P> {146	pub fn new(client: Arc<C>) -> Self {147		Self {148			client,149			_marker: Default::default(),150		}151	}152}153154pub enum Error {155	RuntimeError,156}157158impl From<Error> for i64 {159	fn from(e: Error) -> i64 {160		match e {161			Error::RuntimeError => 1,162		}163	}164}165166macro_rules! pass_method {167	(168		$method_name:ident($($name:ident: $ty:ty),* $(,)?) -> $result:ty $(=> $mapper:expr)?169		$(; changed_in $ver:expr, $changed_method_name:ident ($($changed_name:expr), * $(,)?) => $fixer:expr)*170	) => {171		fn $method_name(172			&self,173			$(174				$name: $ty,175			)*176			at: Option<<Block as BlockT>::Hash>,177		) -> Result<$result> {178			let api = self.client.runtime_api();179			let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));180			let _api_version = if let Ok(Some(api_version)) =181				api.api_version::<dyn UniqueRuntimeApi<Block, CrossAccountId, AccountId>>(&at)182			{183				api_version184			} else {185				// unreachable for our runtime186				return Err(RpcError {187					code: ErrorCode::InvalidParams,188					message: "Api is not available".into(),189					data: None,190				})191			};192193			let result = $(if _api_version < $ver {194				api.$changed_method_name(&at, $($changed_name),*).map(|r| r.map($fixer))195			} else)*196			{ api.$method_name(&at, $($name),*) };197198			let result = result.map_err(|e| RpcError {199				code: ErrorCode::ServerError(Error::RuntimeError.into()),200				message: "Unable to query".into(),201				data: Some(format!("{:?}", e).into()),202			})?;203			result.map_err(|e| RpcError {204				code: ErrorCode::InvalidParams,205				message: "Runtime returned error".into(),206				data: Some(format!("{:?}", e).into()),207			})$(.map($mapper))?208		}209	};210}211212#[allow(deprecated)]213impl<C, Block, CrossAccountId, AccountId>214	UniqueApi<<Block as BlockT>::Hash, CrossAccountId, AccountId> for Unique<C, Block>215where216	Block: BlockT,217	AccountId: Decode,218	C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,219	C::Api: UniqueRuntimeApi<Block, CrossAccountId, AccountId>,220	CrossAccountId: pallet_evm::account::CrossAccountId<AccountId>,221{222	pass_method!(account_tokens(collection: CollectionId, account: CrossAccountId) -> Vec<TokenId>);223	pass_method!(token_exists(collection: CollectionId, token: TokenId) -> bool);224	pass_method!(225		token_owner(collection: CollectionId, token: TokenId) -> Option<CrossAccountId>;226		changed_in 2, token_owner_before_version_2(collection, token) => |u| Some(u)227	);228	pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);229	pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);230	pass_method!(collection_tokens(collection: CollectionId) -> u32);231	pass_method!(account_balance(collection: CollectionId, account: CrossAccountId) -> u32);232	pass_method!(balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> String => |v| v.to_string());233	pass_method!(allowance(collection: CollectionId, sender: CrossAccountId, spender: CrossAccountId, token: TokenId) -> String => |v| v.to_string());234235	pass_method!(adminlist(collection: CollectionId) -> Vec<CrossAccountId>);236	pass_method!(allowlist(collection: CollectionId) -> Vec<CrossAccountId>);237	pass_method!(allowed(collection: CollectionId, user: CrossAccountId) -> bool);238	pass_method!(last_token_id(collection: CollectionId) -> TokenId);239	pass_method!(collection_by_id(collection: CollectionId) -> Option<Collection<AccountId>>);240	pass_method!(collection_stats() -> CollectionStats);241	pass_method!(next_sponsored(collection: CollectionId, account: CrossAccountId, token: TokenId) -> Option<u64>);242	pass_method!(effective_collection_limits(collection_id: CollectionId) -> Option<CollectionLimits>);243}