Icon HelpCircleForumIcon Link

⌘K

Icon HelpCircleForumIcon Link

Icon LinkMetadata Functionality

For implementation details on the Asset Library metadata functionality please see the Sway Libs Docs Icon Link.

Icon LinkImporting the Asset Library Metadata Functionality

In order to use the Asset Library, Sway Libs and Sway Standards Icon Link must be added to the Forc.toml file and then imported into your Sway project. To add Sway Libs as a dependency to the Forc.toml file in your project please see the Getting Started . To add Sway Standards as a dependency please see the Sway Standards Book Icon Link.

To import the Asset Library Base Functionality and SRC-7 Icon Link Standard to your Sway Smart Contract, add the following to your Sway file:

use sway_libs::asset::metadata::{_metadata, _set_metadata, SetAssetMetadata, StorageMetadata};
use standards::src7::*;

Icon LinkIntegration with the SRC-7 Standard

The SRC-7 Icon Link definition states that the following abi implementation is required for any Native Asset on Fuel which uses stateful metadata:

abi SRC7 {
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata>;
}

The Asset Library has the following complimentary data type for the SRC-7 Icon Link standard:

  • StorageMetadata

Icon LinkSetting Up Storage

Once imported, the Asset Library's metadata functionality should be available. To use them, be sure to add the storage block below to your contract which enables the SRC-7 Icon Link standard.

storage {
    metadata: StorageMetadata = StorageMetadata {},
}

Icon LinkUsing the StorageMetadata Type

Icon LinkSetting Metadata

As described in the SRC-7 Icon Link standard, the metadata type is a simple enum of the following types:

  • b256
  • Bytes
  • u64
  • String

To set some metadata of any of the above types for an Asset, you can use the SetAssetMetadata ABI provided by the Asset Library with the _set_metadata() function. Be sure to follow the SRC-9 Icon Link standard for your key. It is recommended that the Ownership Library is used in conjunction with the SetAssetMetadata ABI to ensure only a single user has permissions to set an Asset's metadata.

The _set_metadata() function follows the SRC-7 standard for logging and will emit the SetMetadataEvent when called.

use sway_libs::asset::metadata::*;
use standards::src7::Metadata;
 
storage {
    metadata: StorageMetadata = StorageMetadata {},
}
 
impl SetAssetMetadata for Contract {
    #[storage(read, write)]
    fn set_metadata(asset: AssetId, key: String, metadata: Metadata) {
        // add your authentication logic here
        // eg. only_owner()
        _set_metadata(storage.metadata, asset, key, metadata);
    }
}
Icon InfoCircle

NOTE The _set_metadata() function will set the metadata of an asset unconditionally. External checks should be applied to restrict the setting of metadata.

To set the metadata of an Asset, using only one of the above types, you can define a custom ABI and use it as such:

abi CustomSetAssetMetadata {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    );
}
 
impl CustomSetAssetMetadata for Contract {
    #[storage(read, write)]
    fn custom_set_metadata(
        asset: AssetId,
        key: String,
        bits256: b256,
        bytes: Bytes,
        int: u64,
        string: String,
    ) {
        let b256_metadata = Metadata::B256(bits256);
        let bytes_metadata = Metadata::Bytes(bytes);
        let int_metadata = Metadata::Int(int);
        let string_metadata = Metadata::String(string);
 
        // your authentication logic here
 
        // set whichever metadata you want
        storage.metadata.insert(asset, key, string_metadata);
    }
}
Icon InfoCircle

NOTE The _set_metadata() function will set the metadata of an asset unconditionally. External checks should be applied to restrict the setting of metadata.

Icon LinkImplementing the SRC-7 Standard with StorageMetadata

To use the StorageMetadata type, simply get the stored metadata with the associated key and AssetId using the provided _metadata() convenience function. The example below shows the implementation of the SRC-7 Icon Link standard in combination with the Asset Library's StorageMetadata type and the _metadata() function with no user defined restrictions or custom functionality.

use sway_libs::asset::metadata::*;
use standards::src7::{Metadata, SRC7};
 
storage {
    metadata: StorageMetadata = StorageMetadata {},
}
 
// Implement the SRC-7 Standard for this contract
impl SRC7 for Contract {
    #[storage(read)]
    fn metadata(asset: AssetId, key: String) -> Option<Metadata> {
        // Return the stored metadata
        storage.metadata.get(asset, key)
    }
}

Icon LinkGetting Metadata

To get the metadata for an asset, apart from the above mentioned _metadata() convenience function, you can also use the get() method on the StorageMetadata type, which returns the Metadata type.

use sway_libs::asset::metadata::*; // To access trait implementations you must import everything using the glob operator.
let metadata: Option<Metadata> = storage.metadata.get(asset, key);

This results an Option type as the metadata may not be set for the asset and key combination.

If you know that the metadata is set, but you don't know the type, you can use a match statement to access the metadata.

    match metadata.unwrap() {
        Metadata::B256(b256) => {
        // do something with b256
},
        Metadata::Bytes(bytes) => {
        // do something with bytes
},
        Metadata::Int(int) => {
        // do something with int
},
        Metadata::String(string) => {
        // do something with string
},
    }

If you know that the metadata is set and you know the type, you can use the as_* methods to access the metadata. We also provide is_* methods to check if the metadata is of a specific type.

let metadata: Metadata = storage.metadata.get(asset, key).unwrap();
 
if metadata.is_b256() {
    let b256: b256 = metadata.as_b256().unwrap();
    // do something with b256
} else if metadata.is_bytes() {
    let bytes: Bytes = metadata.as_bytes().unwrap();
    // do something with bytes
} else if metadata.is_u64() {
    let int: u64 = metadata.as_u64().unwrap();
    // do something with int
} else if metadata.is_string() {
    let string: String = metadata.as_string().unwrap();
    // do something with string
}