4

I am trying to implement custom rpc using the tutorial : https://substrate.recipes/custom-rpc.html, I successfully implemented silly rpc but getting error for runtime api rpc.

Here are my code: template/rpc/src/lib.rs

use jsonrpc_core::{Error as RpcError, ErrorCode, Result};
use jsonrpc_derive::rpc;
use sp_api::ProvideRuntimeApi;
use sp_blockchain::HeaderBackend;
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
use std::sync::Arc;
use shivarthu_runtime_api::ShivarthuApi as ShivarthuRuntimeApi;


#[rpc]
pub trait ShivarthuApi<BlockHash> {
    #[rpc(name= "shivarthu_helloWorld")]
    fn hello_world(&self, at: Option<BlockHash>) -> Result<u128>;
}


pub struct Shivarthu<C, M> {
    client: Arc<C>,
    _marker: std::marker::PhantomData<M>,
}

impl<C, M> Shivarthu<C, M> {
    pub fn new(client: Arc<C>) -> Self {
        Self {
            client,
            _marker: Default::default(),
        }
    }
}


impl<C, Block> ShivarthuApi<<Block as BlockT>::Hash> for Shivarthu<C, Block>
where
    Block: BlockT,
    C: Send + Sync + 'static,
    C: ProvideRuntimeApi<Block>,
    C: HeaderBackend<Block>,
    C::Api: ShivarthuRuntimeApi<Block>,
{
    fn hello_world(&self, at: Option<<Block as BlockT>::Hash>) -> Result<u128> {
        let api = self.client.runtime_api();
        let at = BlockId::hash(at.unwrap_or_else(||
            // If the block hash is not supplied assume the best block.
            self.client.info().best_hash));

        let runtime_api_result = api.hello_world(&at);
        runtime_api_result.map_err(|e| RpcError {
            code: ErrorCode::ServerError(9876), // No real reason for this value
            message: "Something wrong".into(),
            data: Some(format!("{:?}", e).into()),
        })
    }
}

In node/src/rpc.rs

io.extend_with(shivarthu_rpc::ShivarthuApi::to_delegate(
        shivarthu_rpc::Shivarthu::new(client),
    ));

It gives error:

io.extend_with(shivarthu_rpc::ShivarthuApi::to_delegate(
   |                    ---------------------------------------- required by a bound introduced by this call
58 |         shivarthu_rpc::Shivarthu::new(client),
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `shivarthu_runtime_api::ShivarthuApi<sp_runtime::generic::Block<sp_runtime::generic::Header<u32, BlakeTwo256>, OpaqueExtrinsic>>` is not implemented for `<C as ProvideRuntimeApi<sp_runtime::generic::Block<sp_runtime::generic::Header<u32, BlakeTwo256>, OpaqueExtrinsic>>>::Api`
   |
   = note: required because of the requirements on the impl of `ShivarthuApi<H256>` for `Shivarthu<C, sp_runtime::generic::Block<sp_runtime::generic::Header<u32, BlakeTwo256>, OpaqueExtrinsic>>`
help: consider further restricting the associated type
   |
36 |     P: TransactionPool + 'static, <C as ProvideRuntimeApi<sp_runtime::generic::Block<sp_runtime::generic::Header<u32, BlakeTwo256>, OpaqueExtrinsic>>>::Api: shivarthu_runtime_api::ShivarthuApi<sp_runtime::generic::Block<sp_runtime::generic::Header<u32, BlakeTwo256>, OpaqueExtrinsic>>

1 Answer 1

4

Ya got it,

The error was because of file node/src/rpc.rs

pub fn create_full<C, P>(deps: FullDeps<C, P>) -> jsonrpc_core::IoHandler<sc_rpc::Metadata>
where
    C: ProvideRuntimeApi<Block>,
    C: HeaderBackend<Block> + HeaderMetadata<Block, Error = BlockChainError> + 'static,
    C: Send + Sync + 'static,
    C::Api: substrate_frame_rpc_system::AccountNonceApi<Block, AccountId, Index>,
    C::Api: pallet_transaction_payment_rpc::TransactionPaymentRuntimeApi<Block, Balance>,
    C::Api: BlockBuilder<Block>,
    C::Api: shivarthu_runtime_api::ShivarthuApi<Block>,
    P: TransactionPool + 'static,
{

I didn't put this line:

C::Api: shivarthu_runtime_api::ShivarthuApi<Block>,
1
  • 1
    I had the same issue and this solved my issue!
    – andresvsm
    Commented Apr 17, 2022 at 11:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.