Skip to content

Commit

Permalink
docs: add token group docs (#6017)
Browse files Browse the repository at this point in the history
* docs: add token group docs

* token group interface: add README

* address README feedback

* address extension doc feedback

* add blurb about SPL Token programs to README

* use state discrims not instructions!
  • Loading branch information
Joe C authored Jan 5, 2024
1 parent 480c6d9 commit ef5b4aa
Show file tree
Hide file tree
Showing 2 changed files with 293 additions and 0 deletions.
155 changes: 155 additions & 0 deletions docs/src/token-2022/extensions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1763,3 +1763,158 @@ Coming soon!

</TabItem>
</Tabs>

### Group Pointer

Similar to the metadata pointer, the group pointer allows a token creator to
designate a group account that describes the mint. However, rather than
describing token metadata, the group account describes configurations for
grouping tokens together.

When a Token-2022 mint possesses a group pointer, the mint is considered to be
a group mint (for example a Collection NFT). Group mints have configurations
that allow them to be used as a point of reference for a related set of tokens.

Similar to metadata, the group pointer can point to the mint itself, and a
client must check that the mint and the group both point to each other.

#### Example: Create a mint with a group pointer to an external account

<Tabs className="unique-tabs" groupId="language-selection">
<TabItem value="cli" label="CLI" default>

```console
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --group-address 7ZJVSav7y76M41eFeyA3xz39UDigQspVNwyJ469TgR1S
Creating token EUMhJgfvjZa7Lb7fSqfD6WCUwELzzRVKunKSnSi4xK42 under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb

Address: EUMhJgfvjZa7Lb7fSqfD6WCUwELzzRVKunKSnSi4xK42
Decimals: 9

Signature: 3ug4Ejs16jJgEm1WyBwDDxzh9xqPzQ3a2cmy1hSYiPFcLQi9U12HYF1Dbhzb2bx75SSydfU6W4e11dGUXaPbJqVc
```

</TabItem>
<TabItem value="jsx" label="JS">

Coming soon!

</TabItem>
</Tabs>

### Group

Token-2022 supports grouping of tokens through the group extension. The
configurations for a group, which describe things like the update authority
and the group's maximum size, can be stored directly in the mint itself.

Token-2022 implements all of the instructions from the
[spl-token-group-interface](https://github.com/solana-labs/solana-program-library/tree/master/token-group/interface).

The group extension works directly with the group-pointer extension.
To intialize group configurations within a mint, you must add the group-pointer
extension, pointed at the mint itself, during mint creation.

The tools do this for you automatically.

#### Example: Create a mint with group configurations

<Tabs className="unique-tabs" groupId="language-selection">
<TabItem value="cli" label="CLI" default>

```console
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --enable-group
Creating token 812A34SxxYx9KqFwUNAuW7Wpwtmuj2pc5u1TGQcvPnj3 under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
To initialize group configurations inside the mint, please run `spl-token initialize-group 812A34SxxYx9KqFwUNAuW7Wpwtmuj2pc5u1TGQcvPnj3 <MAX_SIZE>`, and sign with the mint authority.

Address: 812A34SxxYx9KqFwUNAuW7Wpwtmuj2pc5u1TGQcvPnj3
Decimals: 9

Signature: 2BZH8KE7zVcBj7Mmnu6uCM9NT4ey7qHasZmEk6Bt3tyx1wKCXS3JtcgEvrXXEMFB5numQgA9wvR67o2Z4YQdEw7m

$ spl-token initialize-group 812A34SxxYx9KqFwUNAuW7Wpwtmuj2pc5u1TGQcvPnj3 12 --update-authority 3pGiHDDek35npQuyWQ7FGcWxqJdHvVPDHDDmBFs2YxQj
Signature: 2H16XtBqdwSbvvq8g5o2jhy4TknP6zgt71KHawEdyPvNuvusQrV4dPccUrMqjFeNTbk75AtzmzUVueH3yWiTjBCG
```

</TabItem>
<TabItem value="jsx" label="JS">

Coming soon!

</TabItem>
</Tabs>

### Member Pointer

Similar to the metadata pointer and group pointer, the member pointer allows a
token creator to designate a member account that describes the mint. This
pointer describes configurations for a mint's membership of a group.

When a Token-2022 mint possesses a member pointer, the mint is considered to be
a member mint (for example an NFT that belongs to a collection).

Similar to metadata and group, the member pointer can point to the mint itself,
and a client must check that the mint and the member both point to each other.

#### Example: Create a mint with a member pointer to an external account

<Tabs className="unique-tabs" groupId="language-selection">
<TabItem value="cli" label="CLI" default>

```console
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --member-address CXWuFdWifFQSvMMZ3UxZZVKtjYi2bZt89f5v3yV8zdVE
Creating token 5anZzJbbj6rBkrXW7zzw7MH28xXufj7AB5oKX1Cv4fdh under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb

Address: 5anZzJbbj6rBkrXW7zzw7MH28xXufj7AB5oKX1Cv4fdh
Decimals: 9

Signature: 3ug4Ejs16jJgEm1WyBwDDxzh9xqPzQ3a2cmy1hSYiPFcLQi9U12HYF1Dbhzb2bx75SSydfU6W4e11dGUXaPbJqVc
```

</TabItem>
<TabItem value="jsx" label="JS">

Coming soon!

</TabItem>
</Tabs>

### Member

The member extension also plays a key role in managing groups of tokens with
Token-2022. The configurations for a member, which describe things like the
group address and the member's number, can be stored directly in the mint
itself.

The member extension, like the group extension, works directly with the
member-pointer extension. To intialize member configurations within a mint,
you must add the member-pointer extension, pointed at the mint itself, during
mint creation.

The tools do this for you automatically.

#### Example: Create a mint with member configurations

<Tabs className="unique-tabs" groupId="language-selection">
<TabItem value="cli" label="CLI" default>

```console
$ spl-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb create-token --enable-member
Creating token 9uyqmf9Ued4yQKi4hXT5wMzPF5Nv1S6skAjkjxcCaAyV under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb
To initialize group member configurations inside the mint, please run `spl-token initialize-member 9uyqmf9Ued4yQKi4hXT5wMzPF5Nv1S6skAjkjxcCaAyV`, and sign with the mint authority.

Address: 9uyqmf9Ued4yQKi4hXT5wMzPF5Nv1S6skAjkjxcCaAyV
Decimals: 9

Signature: 2BZH8KE7zVcBj7Mmnu6uCM9NT4ey7qHasZmEk6Bt3tyx1wKCXS3JtcgEvrXXEMFB5numQgA9wvR67o2Z4YQdEw7m

$ spl-token initialize-member 9uyqmf9Ued4yQKi4hXT5wMzPF5Nv1S6skAjkjxcCaAyV --update-authority 3pGiHDDek35npQuyWQ7FGcWxqJdHvVPDHDDmBFs2YxQj
Signature: 2H16XtBqdwSbvvq8g5o2jhy4TknP6zgt71KHawEdyPvNuvusQrV4dPccUrMqjFeNTbk75AtzmzUVueH3yWiTjBCG
```

</TabItem>
<TabItem value="jsx" label="JS">

Coming soon!

</TabItem>
</Tabs>
138 changes: 138 additions & 0 deletions token-group/interface/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
## Token-Group Interface

An interface describing the instructions required for a program to implement
to be considered a "token-group" program for SPL token mints. The interface can
be implemented by any program.

With a common interface, any wallet, dapp, or on-chain program can read the
group or member configurations, and any tool that creates or modifies group
or member configurations will just work with any program that implements the
interface.

This interface is compatible with any program that implements the SPL Token
interface. However, other program implementations that are not SPL Token
programs may still be compatible with an SPL Token Group program should that
program's token standard support the proper components such as mint and mint
authority accounts (see [Required Instructions](#required-instructions)).

There are also structs for `TokenGroup` and `TokenGroupMember` that may
optionally be implemented, but are not required.

### Example program

An example program demonstrating how to implement the SPL Token-Group Interface
can be found in the
[example](https://github.com/solana-labs/solana-program-library/tree/master/token-group/example)
directory alongside this interface's directory.

In addition to demonstrating what a token-group program might look like, it
also provides some reference examples for using the SPL Type Length Value
library to manage TLV-encoded data within account data.

For more information on SPL Type Length Value you can reference the library's
[source code](https://github.com/solana-labs/solana-program-library/tree/master/libraries/type-length-value).

### Motivation

As developers have engineered more creative ways to customize tokens and use
them to power applications, communities, and more, the reliance on tokens that
are intrinsically related through on-chain mapping has continued to strengthen.

Token-group provides developers with the minimum necessary interface components
required to create these relational mappings, allowing for reliable
composability as well as the freedom to customize these groups of tokens
however one might please.

By implementing token-group, on-chain programs can build brand-new kinds of
token groups, which can all overlap with each other and share common tooling.

### Required Instructions

All of the following instructions are listed in greater detail in the source code.

- [`InitializeGroup`](https://github.com/solana-labs/solana-program-library/blob/master/token-group/interface/src/instruction.rs#L22)
- [`UpdateGroupMaxSize`](https://github.com/solana-labs/solana-program-library/blob/master/token-group/interface/src/instruction.rs#L33)
- [`UpdateGroupAuthority`](https://github.com/solana-labs/solana-program-library/blob/master/token-group/interface/src/instruction.rs#L42)
- [`InitializeMember`](https://github.com/solana-labs/solana-program-library/blob/master/token-group/interface/src/instruction.rs#L51)

#### Initialize Group

Initializes a token-group TLV entry in an account for group configurations with
a provided maximum group size and update authority.

Must provide an SPL token mint and be signed by the mint authority.

#### Update Group Max Size

Updates the maximum size limit of a group.

Must be signed by the update authority.

#### Update Group Authority

Sets or unsets the token-group update authority, which signs any future updates
to the group configurations.

Must be signed by the update authority.

#### Initialize Member

Initializes a token-group TLV entry in an account for group member
configurations.

Must provide an SPL token mint for both the group and the group member.

Must be signed by the member mint's mint authority _and_ the group's update
authority.

### (Optional) State

A program that implements the interface may write the following data fields
into a type-length-value entry into an account. Note the type discriminants
for each.

For a group:

```rust
type OptionalNonZeroPubkey = Pubkey; // if all zeroes, interpreted as `None`
type PodU32 = [u8; 4];
type Pubkey = [u8; 32];

/// Type discriminant: [214, 15, 63, 132, 49, 119, 209, 40]
/// First 8 bytes of `hash("spl_token_group_interface:group")`
pub struct TokenGroup {
/// The authority that can sign to update the group
pub update_authority: OptionalNonZeroPubkey,
/// The associated mint, used to counter spoofing to be sure that group
/// belongs to a particular mint
pub mint: Pubkey,
/// The current number of group members
pub size: PodU32,
/// The maximum number of group members
pub max_size: PodU32,
}
```

For a group member:

```rust
/// Type discriminant: [254, 50, 168, 134, 88, 126, 100, 186]
/// First 8 bytes of `hash("spl_token_group_interface:member")`
pub struct TokenGroupMember {
/// The associated mint, used to counter spoofing to be sure that member
/// belongs to a particular mint
pub mint: Pubkey,
/// The pubkey of the `TokenGroup`
pub group: Pubkey,
/// The member number
pub member_number: PodU32,
}
```

By storing the configurations for either groups or group members in a TLV
structure, a developer who implements this interface can freely add any other
data fields in a different TLV entry.

As mentioned previously, you can find more information about
TLV / type-length-value structures at the
[spl-type-length-value repo](https://github.com/solana-labs/solana-program-library/tree/master/libraries/type-length-value).

0 comments on commit ef5b4aa

Please sign in to comment.