Create token that requires interaction with a specific service to use.
default state
extension enables developers to set new token accounts for
a mint with this extension to be frozen by default, requiring interaction with
a specific service to unfreeze and utilize the tokens.freezeAuthority
is the only address that can freeze and thaw a token
accountdefault state
can be updated using updateDefaultAccountState
default state
extension and
creating a new token account which is set to a frozen state upon creation. The
lab includes tests to ensure the extension works as intended for both minting
and transferring tokens in frozen and thawed states.default state
extension allows developers to force all new token accounts
to be in one of two states: “Initialized” or “Frozen”. Most usefully, with this
extension any new token accounts created can be set to frozen. When a token
account is frozen, it’s balance cannot change. Meaning it cannot be minted to,
transferred from or burned. Only the freezeAuthority
can thaw a frozen
account.
Imagine you’re a Nexis Native Chain game dev, and you only want players of your game to
interact with your in-game token. You can make the player, sign up for the game
to thaw their token account and allow them to play and trade with other players.
This works because of the default state
extension, where it is set that all
new token accounts are frozen.
default state
only deals with the latter two: Initialized
and
Frozen
. When you freeze an account, the state is Frozen
, when you thaw, it
is Initialized
.
SystemProgram.createAccount
createInitializeTransferFeeConfigInstruction
createInitializeMintInstruction
SystemProgram.createAccount
allocates space on the
blockchain for the mint account. This instruction accomplishes three things:
space
lamports
for rentgetMintLen
, and to grab the
lamports needed for the space, we call getMinimumBalanceForRentExemption
.
createInitializeDefaultAccountStateInstruction
initializes the
default account state extension.
createInitializeMintInstruction
initializes the mint.
updateDefaultAccountState
.
freezeAuthority
to another account. Say you
want to handle the freezing and thawing by a program for example. You can do
this, by calling setAuthority
, adding in the correct accounts and passing in
the authorityType
, which in this case would be AuthorityType.FreezeAccount
.
default state
extension. We will then write tests
to check if the extension is working as intended by attempting to mint and
transfer the tokens in a frozen and thawed account state.
default-account-state
and
navigate to it. We’ll be initializing a brand new project. Run npm init
and
follow through the prompts.
Next, we’ll need to add our dependencies. Run the following to install the
required packages:
src
. In this directory, create a file named
index.ts
. This is where we will run checks against the rules of this
extension. Paste the following code in index.ts
:
index.ts
creates a connection to the specified validator node and calls
initializeKeypair
. It also has a few variables we will be using in the rest of
this lab. The index.ts
is where we’ll end up calling the rest of our script
once we’ve written it.
If you run into an error in initializeKeypair
with airdropping, follow the
next step.
solana-test-validator
. This
will run the node and also log out some keys and values. The value we need to
retrieve and use in our connection is the JSON RPC URL, which in this case is
http://127.0.0.1:8899
. We then use that in the connection to specify to use
the local RPC URL.
clusterApiUrl
from @nexis-network/web3.js
and pass it to the connection as such:
keypairPath
parameter to initializeKeypair
. You can get this from
running solana config get
in your terminal. And then go to
faucet.nexis.network and airdrop some sol to your
address. You can get your address from running solana address
in your
terminal.
index.ts
code from earlier, we added the following helpers:
initializeKeypair
: This function creates the keypair for the payer
and
also airdrops some NZT to itmakeKeypairs
: This function creates keypairs without airdropping any NZTpayer
: Used to pay for and be the authority for everythingmintKeypair
: Our mint that will have the default state
extensionourTokenAccountKeypair
: The token account owned by payer that we’ll use for
testingotherTokenAccountKeypair
: Another token used for testingcreateTokenExtensionMintWithDefaultState
in src/mint-helpers.ts
. This function will create the mint such that all new
token accounts will be “frozen” to start. The function will take the following
arguments:
connection
: The connection objectpayer
: Payer for the transactionmintKeypair
: Keypair for the new mintdecimals
: Mint decimalsdefaultState
: Mint token default state - eg: AccountState.Frozen
SystemProgram.createAccount
method. This requires specifying the payer’s
keypair, (the account that will fund the creation and provide NZT for rent
exemption), the new mint account’s public key (mintKeypair.publicKey
), the
space required to store the mint information on the blockchain, the amount of
NZT (lamports) necessary to exempt the account from rent and the ID of the token
program that will manage this mint account (TOKEN_2022_PROGRAM_ID
).
createInitializeDefaultAccountStateInstruction
function is
used to generate an instruction that enables the mint to set defaultState
of
any new token accounts.
createInitializeMintInstruction
and passing in the required arguments. This function is provided by the SPL
Token package and it constructs a transaction instruction that initializes a new
mint.
src/mint-helpers.ts
file will look like
this:
frozen
. To do this we call
the createTokenExtensionMintWithDefaultState
function we just created in out
index.ts
file:
createAccount
helper provided by the SPL Token library. We will
use the keypairs we generated at the beginning: ourTokenAccountKeypair
and
otherTokenAccountKeypair
.
default state
extension.
We’ll write four tests in total:
ourTokenAccount
without thawing the
account. This test is expected to fail as the account will be frozen on the mint
attempt. Remember: when a token account is frozen, the balance cannot change.
To do this, let’s wrap a mintTo
function in a try catch
and print out the
respected result:
✅ - We expected this to fail because the account is still frozen.
thawAccount
and then mintTo
:
otherTokenAccountKeypair
is frozen due to the
extension.
Again, we expect this test to fail, since the otherTokenAccountKeypair
is
frozen and it’s balance cannot change.
To test this, let’s wrap a transfer
function in a try catch
:
thawAccount
and then transfer
:
default state
extension, enforces the default state on all new token
accounts.