3

I'm trying to create a custom RPC for my pallet. I've followed Substrate Recipes (I know it's outdated but helped a lot) and pallet_transaction for Runtime API and RPC.

My first RPC, profile_getSum, works as expected. However, profile_getProProfiles has 2 params, and has an error when I try to request.

api.rpc.profile.getProProfiles("0x00", "toronto")

What I've Tried:

const profession = api.createType('ProfilePrimitivesProfession', 'None');
  • api.rpc.profile.getProProfiles("None", "toronto")
  • api.rpc.profile.getProProfiles(profession.toHex(), "toronto")
  • api.rpc.profile.getProProfiles(profession.toRawType(), "toronto")
#[rpc]
pub trait ProfileStorageApi<BlockHash, Hash> {
    #[rpc(name = "profile_getSum")]
    fn get_sum(&self, at: Option<BlockHash>) -> Result<u8>;

    #[rpc(name = "profile_getProProfiles")]
    fn get_pro_profiles(
        &self,
        at: Option<BlockHash>,
        profession: Profession,
        area: Vec<u8>,
    ) -> Result<Vec<Profile<Hash>>>;
}
#[derive(Encode, Decode, Clone, Copy, PartialEq, sp_core::RuntimeDebug, TypeInfo)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum Profession { None, Doctor, Writer }
2022-03-04 16:51:15.760 TRACE ThreadId(82) rpc: Request: {"id":65,"jsonrpc":"2.0","method":"profile_getProProfiles","params":["None","0x746f726f6e746f"]}.    
2022-03-04 16:51:15.760 TRACE ThreadId(82) rpc_metrics: [ws] profile_getProProfiles call: MethodCall(MethodCall { jsonrpc: Some(V2), method: "profile_getProProfiles", params: Array([String("None"), String("0x746f726f6e746f")]), id: Num(65) })
2022-03-04 16:51:15.760 DEBUG tokio-runtime-worker rpc_metrics: [ws] profile_getProProfiles call took 98 μs
2022-03-04 16:51:15.760 DEBUG tokio-runtime-worker rpc: Response: {"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: invalid length 4, expected a (both 0x-prefixed or not) hex string with length of 64."},"id":65}.

Update

I've come across Subsocial's node. Since it has similar RPC methods (having an enum parameter in the runtime-api) with mine it would be a good example.

Subsocial's FlatPostKind enum

#[derive(Encode, Decode, Ord, PartialOrd, Clone, Eq, PartialEq)]
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
pub enum FlatPostKind {
    RegularPost,
    Comment,
    SharedPost
}

RPC method

#[rpc(name = "posts_getPublicPosts")]
fn get_public_posts(
    &self,
    at: Option<BlockHash>,
    kind_filter: Vec<FlatPostKind>,
    start_id: u64,
    limit: u16
) -> Result<Vec<FlatPost<AccountId, BlockNumber>>>;

As seen in the fn get_public_posts, it has a parameter that has a type of Vec<FlatPostKind>.

Still can't get a successful response. I believe it's not on @polkadotjs/api side but rather how I try to query.

burak@burak-pc:~$ curl -H "Content-Type: application/json" -d '{"id":"2", "jsonrpc":"2.0", "method": "posts_getPublicPosts", "params":[["RegularPost"], "0", "1"]}' http://localhost:9934

{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: invalid type: sequence, expected a 0x-prefixed hex string with length of 64."},"id":"2"}

1 Answer 1

2

The api docs of enums is worth a review I think. If your chain uses metadata v14, the metadata itself specifies the types completely, no need for manual definitions FYI, we highly suggest the update to include scale-info added here. (Manual enum specification is there currently for historic blocks) Note you must annotate your enum to be included in the metadata, for example:

#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
pub enum PreimageStatus<AccountId, Balance, BlockNumber> {...}

I notice a mismatch in your getProProfiles api call and the fn get_pro_profiles declaration as well, 2 vs. 3 parameters. Likely just need to specify all uniformly before you try again? I believe None is explicitly needed in the api call if you are looking for the Option to be correctly sent over the wire.

2
  • I already use scale-info. I'm not looking to have Option in the enum. Basically, I need an enum parameter for filtering. None is needed for Default. I've edited the question for a more clear enum definition.
    – Burak
    Mar 5, 2022 at 6:35
  • You're right. There are 3 parameters if you include at: Option<BlockHash> which I didn't. Passing null as the first parameter solved the issue.
    – Burak
    Mar 7, 2022 at 9:52

Your Answer

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

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