-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* 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
Showing
2 changed files
with
293 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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). |