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
Creation
Let's create a Social Token as part of a new collective.
First, create a collective:
// Create a simple exponential curve 0.001 sqrt(S)
var curve =await tokenBondingSdk.initializeCurve({
config:newExponentialCurveConfig({
c:0.001,
b:0,
pow:1,
frac:2
})
});
// Create a collective around the Target of the above token bonding
isPrimary:false,// Creates a social token explicitly associated with the collective by pda, instead of the wallet alone.
collective,
metadata:{
name:"Learning Strata Token",
symbol:"luvSTRAT",
uri:"https://strataprotocol.com/luvSTRAT.json",
},
ignoreIfExists:true,// If a Social Token already exists for this wallet, ignore.
tokenBondingParams:{
curve,
buyBaseRoyaltyPercentage:0,
buyTargetRoyaltyPercentage:5,
sellBaseRoyaltyPercentage:0,
sellTargetRoyaltyPercentage:0
}
});
Loading...
Fetch the created token:
var tokenBondingAcct =await tokenBondingSdk.getTokenBonding(tokenBonding);
var ownerTokenRefAcct =await tokenCollectiveSdk.getTokenRef(ownerTokenRef);
Loading...
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.
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
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.
// Explicitly don't have the verifier sign this, it should fail
var txid =await provider.send(nameTx);
Loading...
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.
name: twitterName,// Associate the social token with the created name
metadata:{
name:"Learning Strata Token",
symbol:"luvSTRAT",
uri:"https://strataprotocol.com/luvSTRAT.json",
},
ignoreIfExists:true,// If a Social Token already exists for this name, ignore.
tokenBondingParams:{
curve,
buyBaseRoyaltyPercentage:0,
buyTargetRoyaltyPercentage:5,
sellBaseRoyaltyPercentage:0,
sellTargetRoyaltyPercentage:0
}
});
var tokenBondingAcct =await tokenBondingSdk.getTokenBonding(tokenBonding);
Loading...
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
var space =1000;// Extra space to store things on the name
var instructions =[createInstruction(
NAME_PROGRAM_ID,// name program id
SystemProgram.programId,// system program id
twitterName,// name to create
nameOwner.publicKey,// name owner
provider.wallet.publicKey,// Fee payer, normally we'd make the person claiming the handle pay
var presignedTransaction = transaction.serialize({requireAllSignatures:false,verifySignatures:false}).toJSON()
Loading...
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:
var royaltiesBalance =(await connection.getTokenAccountBalance(tokenBondingAcct.buyTargetRoyalties)).value;
Loading...
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.