diff --git a/LEZ testnet v0.1 tutorials/custom tokens.md b/LEZ testnet v0.1 tutorials/custom tokens.md new file mode 100644 index 00000000..ea647696 --- /dev/null +++ b/LEZ testnet v0.1 tutorials/custom tokens.md @@ -0,0 +1,159 @@ +This tutorial focuses on custom tokens using the Token program. As of now, you have used the authenticated-transfers program for native tokens. The Token program is for creating and managing custom tokens. By the end, you will have practiced: +1. Creating new tokens. +2. Transferring custom tokens. + +> [!Important] +> The Token program is a single program that creates and manages all tokens, so you do not deploy a new program for each token. +> Token program accounts fall into two types: +> - Token definition accounts: store token metadata such as name and total supply. This account is the token’s identifier. +> - Token holding accounts: store balances and the definition ID they belong to. + +The CLI provides commands to execute the Token program. Run `wallet token` to see the options: + +```bash +Commands: + new Produce a new token + send Send tokens from one account to another with variable privacy + help Print this message or the help of the given subcommand(s) +``` + +## 1. Creating new tokens + +Use `wallet token new` to execute the `New` function of the Token program. The command expects: +- A token name. +- A total supply. +- Two uninitialized accounts: +- One for the token definition account. +- One for the token holding account that receives the initial supply. + +### a. Public definition account and public supply account + +1. Create two new public accounts: + +```bash +wallet account new public + +# Output: +Generated new account with account_id Public/4X9kAcnCZ1Ukkbm3nywW9xfCNPK8XaMWCk3zfs1sP4J7 +``` + +```bash +wallet account new public + +# Output: +Generated new account with account_id Public/9RRSMm3w99uCD2Jp2Mqqf6dfc8me2tkFRE9HeU2DFftw +``` + +2. Create the token (Token A): + +```bash +wallet token new \ + --name TOKENA \ + --total-supply 1337 \ + --definition-account-id Public/4X9kAcnCZ1Ukkbm3nywW9xfCNPK8XaMWCk3zfs1sP4J7 \ + --supply-account-id Public/9RRSMm3w99uCD2Jp2Mqqf6dfc8me2tkFRE9HeU2DFftw +``` + +3. Inspect the initialized accounts: + +```bash +wallet account get --account-id Public/4X9kAcnCZ1Ukkbm3nywW9xfCNPK8XaMWCk3zfs1sP4J7 + +# Output: +Definition account owned by token program +{"account_type":"Token definition","name":"TOKENA","total_supply":1337} +``` + +```bash +wallet account get --account-id Public/9RRSMm3w99uCD2Jp2Mqqf6dfc8me2tkFRE9HeU2DFftw + +# Output: +Holding account owned by token program +{"account_type":"Token holding","definition_id":"4X9kAcnCZ1Ukkbm3nywW9xfCNPK8XaMWCk3zfs1sP4J7","balance":1337} +``` + +### b. Public definition account and private supply account + +1. Create fresh accounts for this example: + +> [!Important] +> You cannot reuse the accounts from the previous example. Create new ones here. + +```bash +wallet account new public + +# Output: +Generated new account with account_id Public/GQ3C8rbprTtQUCvkuVBRu3v9wvUvjafCMFqoSPvTEVii +``` + +```bash +wallet account new private + +# Output: +Generated new account with account_id Private/HMRHZdPw4pbyPVZHNGrV6K5AA95wACFsHTRST84fr3CF +With npk 6a2dfe433cf28e525aa0196d719be3c16146f7ee358ca39595323f94fde38f93 +With ipk 03d59abf4bee974cc12ddb44641c19f0b5441fef39191f047c988c29a77252a577 +``` + +2. Create the token (Token B): + +```bash +wallet token new \ + --name TOKENB \ + --total-supply 7331 \ + --definition-account-id Public/GQ3C8rbprTtQUCvkuVBRu3v9wvUvjafCMFqoSPvTEVii \ + --supply-account-id Private/HMRHZdPw4pbyPVZHNGrV6K5AA95wACFsHTRST84fr3CF +``` + +3. Inspect the accounts: + +```bash +wallet account get --account-id Public/GQ3C8rbprTtQUCvkuVBRu3v9wvUvjafCMFqoSPvTEVii + +# Output: +Definition account owned by token program +{"account_type":"Token definition","name":"TOKENB","total_supply":7331} +``` + +```bash +wallet account get --account-id Private/HMRHZdPw4pbyPVZHNGrV6K5AA95wACFsHTRST84fr3CF + +# Output: +Holding account owned by token program +{"account_type":"Token holding","definition_id":"GQ3C8rbprTtQUCvkuVBRu3v9wvUvjafCMFqoSPvTEVii","balance":7331} +``` + +> [!Important] +> As a private account, the supply account is visible only in your local wallet storage. + +## 2. Custom token transfers + +The Token program can move balances between token holding accounts. If the recipient account is uninitialized, the token program will automatically claim it. Use `wallet token send` to execute a transfer. + +### a. Create a recipient account + +```bash +wallet account new public + +# Output: +Generated new account with account_id Public/88f2zeTgiv9LUthQwPJbrmufb9SiDfmpCs47B7vw6Gd6 +``` + +### b. Send 1000 TOKENB to the recipient + +```bash +wallet token send \ + --from Private/HMRHZdPw4pbyPVZHNGrV6K5AA95wACFsHTRST84fr3CF \ + --to Public/88f2zeTgiv9LUthQwPJbrmufb9SiDfmpCs47B7vw6Gd6 \ + --amount 1000 +``` + +### c. Inspect the recipient account + +```bash +wallet account get --account-id Public/88f2zeTgiv9LUthQwPJbrmufb9SiDfmpCs47B7vw6Gd6 + +# Output: +Holding account owned by token program +{"account_type":"Token holding","definition_id":"GQ3C8rbprTtQUCvkuVBRu3v9wvUvjafCMFqoSPvTEVii","balance":1000} +```