git.delta.rocks / unique-network / refs/commits / 57eee2abf728

difftreelog

source

client/rpc/src/lib.rs6.1 KiBsourcehistory
1use std::sync::Arc;23use codec::Decode;4use jsonrpc_core::{Error as RpcError, ErrorCode, Result};5use jsonrpc_derive::rpc;6use up_data_structs::{Collection, CollectionId, CollectionStats, TokenId};7use sp_api::{BlockId, BlockT, ProvideRuntimeApi, ApiExt};8use sp_blockchain::HeaderBackend;9use up_rpc::UniqueApi as UniqueRuntimeApi;1011#[rpc]12pub trait UniqueApi<BlockHash, CrossAccountId, AccountId> {13	#[rpc(name = "unique_accountTokens")]14	fn account_tokens(15		&self,16		collection: CollectionId,17		account: CrossAccountId,18		at: Option<BlockHash>,19	) -> Result<Vec<TokenId>>;20	#[rpc(name = "unique_tokenExists")]21	fn token_exists(22		&self,23		collection: CollectionId,24		token: TokenId,25		at: Option<BlockHash>,26	) -> Result<bool>;2728	#[rpc(name = "unique_tokenOwner")]29	fn token_owner(30		&self,31		collection: CollectionId,32		token: TokenId,33		at: Option<BlockHash>,34	) -> Result<Option<CrossAccountId>>;35	#[rpc(name = "unique_constMetadata")]36	fn const_metadata(37		&self,38		collection: CollectionId,39		token: TokenId,40		at: Option<BlockHash>,41	) -> Result<Vec<u8>>;42	#[rpc(name = "unique_variableMetadata")]43	fn variable_metadata(44		&self,45		collection: CollectionId,46		token: TokenId,47		at: Option<BlockHash>,48	) -> Result<Vec<u8>>;4950	#[rpc(name = "unique_collectionTokens")]51	fn collection_tokens(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<u32>;52	#[rpc(name = "unique_accountBalance")]53	fn account_balance(54		&self,55		collection: CollectionId,56		account: CrossAccountId,57		at: Option<BlockHash>,58	) -> Result<u32>;59	#[rpc(name = "unique_balance")]60	fn balance(61		&self,62		collection: CollectionId,63		account: CrossAccountId,64		token: TokenId,65		at: Option<BlockHash>,66	) -> Result<String>;67	#[rpc(name = "unique_allowance")]68	fn allowance(69		&self,70		collection: CollectionId,71		sender: CrossAccountId,72		spender: CrossAccountId,73		token: TokenId,74		at: Option<BlockHash>,75	) -> Result<String>;7677	#[rpc(name = "unique_adminlist")]78	fn adminlist(79		&self,80		collection: CollectionId,81		at: Option<BlockHash>,82	) -> Result<Vec<CrossAccountId>>;83	#[rpc(name = "unique_allowlist")]84	fn allowlist(85		&self,86		collection: CollectionId,87		at: Option<BlockHash>,88	) -> Result<Vec<CrossAccountId>>;89	#[rpc(name = "unique_allowed")]90	fn allowed(91		&self,92		collection: CollectionId,93		user: CrossAccountId,94		at: Option<BlockHash>,95	) -> Result<bool>;96	#[rpc(name = "unique_lastTokenId")]97	fn last_token_id(&self, collection: CollectionId, at: Option<BlockHash>) -> Result<TokenId>;98	#[rpc(name = "unique_collectionById")]99	fn collection_by_id(100		&self,101		collection: CollectionId,102		at: Option<BlockHash>,103	) -> Result<Option<Collection<AccountId>>>;104	#[rpc(name = "unique_collectionStats")]105	fn collection_stats(&self, at: Option<BlockHash>) -> Result<CollectionStats>;106}107108pub struct Unique<C, P> {109	client: Arc<C>,110	_marker: std::marker::PhantomData<P>,111}112113impl<C, P> Unique<C, P> {114	pub fn new(client: Arc<C>) -> Self {115		Self {116			client,117			_marker: Default::default(),118		}119	}120}121122pub enum Error {123	RuntimeError,124}125126impl From<Error> for i64 {127	fn from(e: Error) -> i64 {128		match e {129			Error::RuntimeError => 1,130		}131	}132}133134macro_rules! pass_method {135	(136		$method_name:ident($($name:ident: $ty:ty),* $(,)?) -> $result:ty $(=> $mapper:expr)?137		$(; changed_in $ver:expr, $changed_method_name:ident ($($changed_name:expr), * $(,)?) => $fixer:expr)*138	) => {139		fn $method_name(140			&self,141			$(142				$name: $ty,143			)*144			at: Option<<Block as BlockT>::Hash>,145		) -> Result<$result> {146			let api = self.client.runtime_api();147			let at = BlockId::hash(at.unwrap_or_else(|| self.client.info().best_hash));148			let _api_version = if let Ok(Some(api_version)) =149				api.api_version::<dyn UniqueRuntimeApi<Block, CrossAccountId, AccountId>>(&at)150			{151				api_version152			} else {153				// unreachable for our runtime154				return Err(RpcError {155					code: ErrorCode::InvalidParams,156					message: "Api is not available".into(),157					data: None,158				})159			};160161			let result = $(if _api_version < $ver {162				api.$changed_method_name(&at, $($changed_name),*).map(|r| r.map($fixer))163			} else)*164			{ api.$method_name(&at, $($name),*) };165166			let result = result.map_err(|e| RpcError {167				code: ErrorCode::ServerError(Error::RuntimeError.into()),168				message: "Unable to query".into(),169				data: Some(format!("{:?}", e).into()),170			})?;171			result.map_err(|e| RpcError {172				code: ErrorCode::InvalidParams,173				message: "Runtime returned error".into(),174				data: Some(format!("{:?}", e).into()),175			})$(.map($mapper))?176		}177	};178}179180impl<C, Block, CrossAccountId, AccountId>181	UniqueApi<<Block as BlockT>::Hash, CrossAccountId, AccountId> for Unique<C, Block>182where183	Block: BlockT,184	AccountId: Decode,185	C: 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,186	C::Api: UniqueRuntimeApi<Block, CrossAccountId, AccountId>,187	CrossAccountId: pallet_common::account::CrossAccountId<AccountId>,188{189	pass_method!(account_tokens(collection: CollectionId, account: CrossAccountId) -> Vec<TokenId>);190	pass_method!(token_exists(collection: CollectionId, token: TokenId) -> bool);191	pass_method!(192		token_owner(collection: CollectionId, token: TokenId) -> Option<CrossAccountId>;193		changed_in 2, token_owner_before_version_2(collection, token) => |u| Some(u)194	);195	pass_method!(const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);196	pass_method!(variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>);197	pass_method!(collection_tokens(collection: CollectionId) -> u32);198	pass_method!(account_balance(collection: CollectionId, account: CrossAccountId) -> u32);199	pass_method!(balance(collection: CollectionId, account: CrossAccountId, token: TokenId) -> String => |v| v.to_string());200	pass_method!(allowance(collection: CollectionId, sender: CrossAccountId, spender: CrossAccountId, token: TokenId) -> String => |v| v.to_string());201202	pass_method!(adminlist(collection: CollectionId) -> Vec<CrossAccountId>);203	pass_method!(allowlist(collection: CollectionId) -> Vec<CrossAccountId>);204	pass_method!(allowed(collection: CollectionId, user: CrossAccountId) -> bool);205	pass_method!(last_token_id(collection: CollectionId) -> TokenId);206	pass_method!(collection_by_id(collection: CollectionId) -> Option<Collection<AccountId>>);207	pass_method!(collection_stats() -> CollectionStats);208}