Skip to main content

Social Tokens

A social token is actually like one large join-table. It is the intersection of

  • A collective
  • An owner's wallet
  • A token mint
  • Token metadata (name, symbol, etc)
  • A bonding curve for that token


Strata has no SocialToken struct; as the token itself is the Social Token. Instead, strata has a TokenRef. The following Entity Relationship Diagram (ERD) shows the state structures on chain


Let's create a Social Token as part of a new collective.

First, create a collective:


We can fetch that data:


Now, create a social token within the collective:


Fetch the created token:


Notice that we created a non-primary social token here. Most wallets will have one social token. For ease of lookup, social tokens refs are a PDA of the owner alone. In the case where one wallet belongs to several collectives, they should choose one isPrimary token that is used for lookups on storefronts.

Unclaimed Creation

Now, let's add an unclaimed token to the collective. You can read more about unclaimed tokens in collectives

Unclaimed tokens make use of the spl-name-service.

The name service allows you to create unique strings on chain owned by a particular wallet. A name consists of

  • Class - The name class must sign the issuance of a name.
  • Owner - The owner of this name
  • Parent - The parent name of this name. In practice, this can be used like a class hierarchy.
  • Parent Owner - The parent name has an owner. If a name has a parent, the parent's owner must also sign the issuance of this name.

This might seem a little abstract, so let's go with an example. Let's say we want to associate unclaimed tokens with twitter users. When a twitter user verifies they own their handle, we let them claim the token. We want to gate who can claim ownership of a twitter handle, so we will assign a verifier keypair as the name class that must approve issuance.

While this example is focused on twitter, this could just as easily work for usernames on your own website. This is a generic framework for onboarding social tokens that users can later claim using their wallet.

This is what we will build:

First, we create a name parent that is our twitter tld


We often refer to a name parent as the Top Level Domain (TLD). In the case of twitter, we have a twitter top level domain that all twitter handles are under.

import { Numberu32, Numberu64, NAME_PROGRAM_ID, createInstruction, createNameRegistry, getNameAccountKey, getHashedName, 
NameRegistryState } from "@solana/spl-name-service";
import { Keypair, SystemProgram, sendAndConfirmRawTransaction } from "@solana/web3.js";

Now we have a top level domain. Every twitter handle must be verified by us, and exist under this top level domain:


Anyone can try to create this name, but without the verifier, the transaction will fail:


Let's create an unclaimed token for the twitter handle "test-...":

Uncreated Name

The name service name for the user does not have to exist for us to create a token for them. We can lazily create the name when the user wants to claim their token. This also allows us to pass the fees for the name creation on to the user.


Now, we create a service that is able to verify the user owns the twitter handle. When the service verifies this twitter handle, it returns a presigned transaction:

Verifier Key

You should keep your verifier key secret, but it will need to be passed in to your server that gate keeps twitter handle creation

Reverse Twitter

The above lets us go from a twitter handle to a wallet. What if we'd like to go from a wallet to a twitter handle? You should look at appending an instruction similar to the reverse-twitter-registry

Now, let's create the name using the presigned transaction


Buy some of the unclaimed coin. This should result in 5% royalties accumulated into a temporary account. Here we can use the Instructions modifier to group these buy calls together:


Now, let's have the user claim the social token. We should see the funds move to their Associated Token Account:

Owned By Name

When creating a collective that allows unclaimed tokens, be sure to include the ownedByName field in the royalties configuration for every account you want to transfer to the name owner.