0

I'm trying to return an item that is within a storageMap. Its key is a Vec(u8), but I don't know how to send this type using a curl call. I tried using the id as string and using its hex version and I receive de following message:

~ % curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "items_getItemById", "params": [1234321] }' http://localhost:9933

{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params: invalid type: integer `1234321`, expected a (both 0x-prefixed or not) hex string with length of 64."},"id":1}

~ % curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "items_getItemById", "params": [0x31323334333231] }' http://localhost:9933

{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}

This is the item stored on chain:

[
  [
    [
      1234321
    ]
    {
      id: 1234321
      summary: 12341234
      owner: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY
      state: ForSale
      price: 23
      lastUpdate: 1234123
      creationBlock: 4
    }
  ]
]

The main issue is that I'm not able to query the item from the following function:

pub fn get_item(id: ProductId) -> Option<ItemRpc> {
    Self::get_item_by_id(&id)
} 

fn get_item_by_id(id: &[u8]) -> Option<ItemRpc> {
    if let Some(value) = Self::items(id) {
        Some(value.to_rpc())
    } else {
        None
    }
}

This is how I create items for the pallet: Creation entry point

UPDATE

This is my rpc and my runtime api for the items pallet:

rpc:

fn get_item(
        &self,
        at: Option<<Block as BlockT>::Hash>,
        id: ProductId
    ) -> Result<Option<ItemRpc>> {
        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.get_item(&at, id);
        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()),
        })
    }

runtime-api:

fn get_item(id: ProductId) -> Option<ItemRpc>;

node runtime:

impl_runtime_apis! {
    fn get_item(id: ProductId) -> Option<ItemRpc> {
        Items::get_item(id)
    }
}

ItemRpc struct:

pub struct ItemRpc {
        pub id: ProductId, // Vec<u8>
        pub summary: H256, // Vec<u8>
        pub owner: [u8; 32],
        pub state: State,
        pub price: Option<u32>,
        pub last_update: Timestamp, // Vec<u8>
        pub creation_block: u32,
    }

2 Answers 2

1

I had the same issue and it answered here. You need to add one more param for Option<BlockHash>

I believe you can try this,

curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "items_getItemById", "params": [null, 1234321] }' http://localhost:9933
5
  • I get the same errors :/ I have another rpc function that retrieves the first element of the storageMap and it works fine, but it seems like I'm doing something wrong or my functions are not getting the item correctly.
    – andresvsm
    Apr 29, 2022 at 6:56
  • 1
    Can you edit the question and add your rpc and runtime api code?
    – Burak
    Apr 29, 2022 at 16:41
  • 1
    id is Vec<u8>, so you need to encode it as a hex string, as per the error message. Pass this via curl as the id 0x31323334333231
    – Jaco
    May 3, 2022 at 10:46
  • @Jaco At the start of the post you can see that I also tried that. Now im getting the same issue even when working with u64 instead of Vec<u8>. Im passing as "params": [null, 1] and now it expects a sequence and not an integer :(
    – andresvsm
    May 9, 2022 at 15:06
  • If you pass an encoded Bytes, you need to pass it explicitly quoted since it is a string, not a number. So this "0x31323334333231" is correct, this 0x31323334333231 is not. (This is why the node error refers to "hex string")
    – Jaco
    May 10, 2022 at 5:13
1

After a few attempts, the only way to make it work was to supply an array of bytes but using ASCII encoding.

Example to query item with id '1234':

~ % curl -H "Content-Type: application/json" -d '{"id":1, "jsonrpc":"2.0", "method": "items_getItemById", "params": [null, [49, 50, 51, 52]] }' http://localhost:9933

After making this work, I was able to query multiple items (1234, 1762) providing a vector of bytes like

"params": [null, [[49, 50, 51, 52], [49, 55, 54, 50]]]

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.