Got error trying to get metadata from a contract implementing the SRC7 standard

I’ve got the following contract in sway which implements the SRC7 standard:

contract;

use src_7::{Metadata, SRC7};
use std::{call_frames::contract_id, hash::Hash, storage::storage_string::*, string::String};

impl SRC7 for Contract {
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        if key == String::from_ascii_str("key") {
            Some(Metadata::String(String::from_ascii_str("value")))
        } else {
            None
        }
    }
}

And when I’m trying to call the metadata function from rust, I’m getting the following error: “Enums currently support only one level deep heap types”. Looks like the rust sdk doesn’t support nested enums, and in the current context both Option and Metadata are enums, nested one into each other in the return parameter of the function.

The way I’m calling the function:

let meta = contract_instance
        .methods()
        .metadata(asset_id, "key".to_string())
        .simulate()
        .await
        .unwrap();

And the error I’m getting:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: InvalidType("Enums currently support only one level deep heap types.")

fuelup show:

Default host: aarch64-apple-darwin
...
active toolchain
-----------------
beta-4-aarch64-apple-darwin (default)
  forc : 0.46.1
    - forc-client
      - forc-deploy : 0.46.1
      - forc-run : 0.46.1
    - forc-doc : 0.46.1
    - forc-explore : 0.28.1
    - forc-fmt : 0.46.1
    - forc-index : 0.23.0
    - forc-lsp : 0.46.1
    - forc-tx : 0.46.1
    - forc-wallet : 0.3.0
  fuel-core : 0.20.5
  fuel-core-keygen : Error getting version string
  fuel-indexer : 0.23.0

fuels versions
---------------
forc : 0.45
forc-wallet : 0.45

fuels-rs version:

fuels = "0.49.0"

Hi there!
It looks like you’ve reached a bleeding edge!

Currently, the Rust SDK cannot handle a nested heap type.

Basically, what you are describing is being tracked in this issue.

Please check the current issue to get more context.

Hey, thanks for the link! I’ll follow the issue. While it’s still there it makes it impossible to properly implement NFTs on Fuel (using the Rust SDK)

Can you please post a full detail of the enum you are using? We fortunately support nested enums, what we don’t support is “heap types” (ie vectors) nested at depth more than 1.

You can find all the types in the standard. The enums are in the same folder: src_7.sw.

Ok so basically it’s because you’re returning an Option<Metadata>. If you were to return a Metadata it would work, because then the Bytes variant of the Metadata type is at depth one. I’m not sure what to advise you here.

It’s not me returning Option<Metadata>, it’s a Fuel’s standard that does this :slight_smile: I’m just trying to follow the standard. Maybe you could communicate it within Fuel and change the standard appropriately?

PS: also, I tried to remove the Option wrapper and I was getting another error related to the rust sdk. I’ll give you details later

1 Like

The issue is the sway standard:

fn metadata(asset: AssetId, key: String) -> Option<Metadata>;

Then, the execution returns something like

let result: Option<Enum<String>> = SRC7.metadata(myAsset, myKey);

Considering:

/// Universal return type for metadata.
pub enum Metadata {
    // Used when the stored metadata is a `b256`.
    B256: b256,
    /// Used when the stored metadata is `Bytes`.
    Bytes: Bytes,
    /// Used when the stored metadata is a `u64`.
    Int: u64,
    /// Used when the stored metadata is a `String`.
    String: String,
}

Thanks for pointing it out @mpoplavkov!

I’m taking this to the sway-standards police with high priority. Check the issue.

3 Likes

Woops sorry I didn’t realize it was Fuel’s own standard :sweat_smile:

2 Likes

Issue moved here.