Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expand asset library docs #322

Merged
merged 7 commits into from
Jan 31, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

- [#318](https://github.com/FuelLabs/sway-libs/pull/318) Adds further documentation and examples for the `signed_integers` library.
- [#319](https://github.com/FuelLabs/sway-libs/pull/319) Adds further documentation and examples for the ownership library.
- [#322](https://github.com/FuelLabs/sway-libs/pull/320) Adds further documentation and examples for the asset metadata library.

### Changed

Expand Down
39 changes: 38 additions & 1 deletion docs/book/src/asset/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,14 @@ Once imported, the Asset Library's metadata functionality should be available. T

### Setting Metadata

To set some metadata for an Asset, use the `SetAssetMetadata` ABI provided by the Asset Library with the `_set_metadata()` function. Be sure to follow the [SRC-9](https://docs.fuel.network/docs/sway-standards/src-9-metadata-keys/) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetMetadata` ABI to ensure only a single user has permissions to set an Asset's metadata.
As described in the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) 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](https://docs.fuel.network/docs/sway-standards/src-9-metadata-keys/) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) 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.

Expand All @@ -46,10 +53,40 @@ The `_set_metadata()` function follows the SRC-7 standard for logging and will e

> **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:

```sway
{{#include ../../../../examples/asset/setting_src7_attributes/src/main.sw:setting_src7_attributes_custom_abi}}
```

> **NOTE** The `_set_metadata()` function will set the metadata of an asset *unconditionally*. External checks should be applied to restrict the setting of metadata.
### Implementing 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](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard in combination with the Asset Library's `StorageMetadata` type and the `_metadata()` function with no user defined restrictions or custom functionality.

```sway
{{#include ../../../../examples/asset/basic_src7/src/main.sw:basic_src7}}
```

### Getting 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.

```sway
{{#include ../../../../examples/asset/metadata_docs/src/main.sw:get_metadata}}
```

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.

```sway
{{#include ../../../../examples/asset/metadata_docs/src/main.sw:get_metadata_match}}
```

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.

```sway
{{#include ../../../../examples/asset/metadata_docs/src/main.sw:get_metadata_as}}
```
45 changes: 45 additions & 0 deletions examples/asset/metadata_docs/src/main.sw
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,52 @@ impl SRC7 for Contract {
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);
}
}
// ANCHOR_END: src7_set_metadata

#[storage(read)]
fn get_metadata(asset: AssetId, key: String) {
// ANCHOR: get_metadata
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);
// ANCHOR_END: get_metadata

// ANCHOR: get_metadata_match
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
},
}
// ANCHOR_END: get_metadata_match

// ANCHOR: get_metadata_as
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
}
// ANCHOR_END: get_metadata_as
}
39 changes: 39 additions & 0 deletions examples/asset/setting_src7_attributes/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
contract;

use std::string::String;
use std::bytes::Bytes;

// ANCHOR: setting_src7_attributes
use sway_libs::asset::metadata::*;
Expand All @@ -13,7 +14,45 @@ storage {
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);
}
}
// ANCHOR_END: setting_src7_attributes

// ANCHOR: setting_src7_attributes_custom_abi
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);
}
}
// ANCHOR_END: setting_src7_attributes_custom_abi
Loading