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

nep-393: add class metadata interface #528

Merged
merged 8 commits into from
Feb 23, 2024
Merged
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
58 changes: 51 additions & 7 deletions neps/nep-0393.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,8 +269,9 @@ The Soulbound Token follows the NFT [NEP-171](https://github.com/near/NEPs/blob/
All time related attributes are defined in milliseconds (as per NEP-171).

```rust
/// ContractMetadata defines contract wide attributes, which describes the whole contract.
pub struct ContractMetadata {
/// IssuerMetadata defines contract wide attributes, which describes the whole contract.
/// Must be provided by the Issuer contract. See the `SBTIssuer` trait.
pub struct IssuerMetadata {
/// Version with namespace, example: "sbt-1.0.0". Required.
pub spec: String,
/// Issuer Name, required, ex. "Mosaics"
Expand All @@ -290,6 +291,25 @@ pub struct ContractMetadata {
pub reference_hash: Option<Base64VecU8>,
}

/// ClassMetadata defines SBT class wide attributes, which are shared and default to all SBTs of
/// the given class. Must be provided by the Issuer contract. See the `SBTIssuer` trait.
pub struct ClassMetadata {
/// Issuer class name. Required to be not empty.
pub name: String,
/// If defined, should be used instead of `IssuerMetadata::symbol`.
pub symbol: Option<String>,
/// An URL to an Icon. To protect fellow developers from unintentionally triggering any
/// SSRF vulnerabilities with URL parsers, we don't allow to set an image bytes here.
/// If it doesn't start with a scheme (eg: https://) then `IssuerMetadata::base_uri`
/// should be prepended.
pub icon: Option<String>,
/// JSON or an URL to a JSON file with more info. If it doesn't start with a scheme
/// (eg: https://) then base_uri should be prepended.
pub reference: Option<String>,
/// Base64-encoded sha256 hash of JSON from reference field. Required if `reference` is included.
pub reference_hash: Option<Base64VecU8>,
}

/// TokenMetadata defines attributes for each SBT token.
pub struct TokenMetadata {
pub class: ClassId, // token class. Required. Must be non zero.
Expand Down Expand Up @@ -448,12 +468,18 @@ Example **Soul Transfer** interface:

### SBT Issuer interface

SBTContract is the minimum required interface to be implemented by issuer. Other methods, such as a mint function, which requests the registry to proceed with token minting, is specific to an Issuer implementation (similarly, mint is not part of the FT standard).
SBTIssuer is the minimum required interface to be implemented by issuer. Other methods, such as a mint function, which requests the registry to proceed with token minting, is specific to an Issuer implementation (similarly, mint is not part of the FT standard).

The issuer must provide metadata object of the Issuer. Optionally, Issuer can also provide metadata object for each token class.
Issuer level (contract) metadata, must provide information common to all tokens and all classes defined by the issuer. Class level metadata, must provide information common to all tokens of a given class. Information should be deduplicated and denormalized whenever possible.
Example: The issuer can set a default icon for all tokens (SBT) using `IssuerMetadata::icon` and additionally it can customize an icon of a particular token via `TokenMetadata::icon`.

```rust
pub trait SBTContract {
/// returns contract metadata
fn sbt_metadata(&self) -> ContractMetadata;
pub trait SBTIssuer {
/// Returns contract metadata.
fn sbt_metadata(&self) -> IssuerMetadata;
/// Returns SBT class metadata, or `None` if the class is not found.
fn sbt_class_metadata(&self, class: ClassId) -> Option<ClassMetadata>;
}
```

Expand Down Expand Up @@ -594,7 +620,7 @@ trait SBT {

## Reference Implementation

- Common [type definitions](https://github.com/near-ndc/i-am-human/tree/main/contracts/sbt) (events, traits).
- Common [type definitions](https://github.com/near-ndc/i-am-human/tree/master/contracts/sbt) (events, traits).
- [I Am Human](https://github.com/near-ndc/i-am-human) registry and issuers.

## Consequences
Expand Down Expand Up @@ -667,6 +693,24 @@ The Contract Standards Working Group members approved this NEP on June 30, 2023
| 9 | [Privacy](https://github.com/near/NEPs/pull/393/#issuecomment-1504309947) | Concerns have been addressed: [comment-1](https://github.com/near/NEPs/pull/393/#issuecomment-1504485420) and [comment2](https://github.com/near/NEPs/pull/393/#issuecomment-1505958549) | resolved |
| 10 | @frol [suggested](https://github.com/near/NEPs/pull/393/#discussion_r1247879778) to use a struct in `sbt_recover` and `sbt_soul_transfer`. | Motivation to use pair `(number, bool)` rather than follow a common Iterator Pattern. Rust uses `Option` type for that, that works perfectly for languages with native Option type, but creates a "null" problem for anything else. Other common way to implement Iterator is the presented pair, which doesn't require extra type definition and reduces code size. | new |


### v1.1.0


In v1.0.0 we defined Issuer (an entity authorized to mint SBTs in the registry) and SBT Class. We also defined Issuer Metadata and Token Metadata, but we didn't provide interface for class metadata. This was implemented in the reference implementation (in one of the subsequent revisions), but was not backported to the NEP. This update:

- Fixes the name of the issuer interface from `SBTContract` to `SBTIssuer`. The original name is wrong and we oversight it in reviews. We talk everywhere about the issuer entity and issuer contract (even the header is SBT Issuer interface).
- Renames `ContractMetadata` to `IssuerMetadata`.
- Adds `ClassMetadata` struct and `sbt_class_metadata` function to the `SBTIssuer` interface.

Reference implementation: [ContractMetadata, ClassMetadata, TokenMetadata](https://github.com/near-ndc/i-am-human/blob/registry/v1.8.0/contracts/sbt/src/metadata.rs#L18) and [SBTIssuer interface](https://github.com/near-ndc/i-am-human/blob/registry/v1.8.0/contracts/sbt/src/lib.rs#L49).

#### Benefits

- Improves the documentation and meaning of the issuer entity.
- Adds missing `ClassMetadata`.
- Improves issuer, class and token metadata documentation.

## Copyright

[Creative Commons Attribution 4.0 International Public License (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/)
Loading