From dbbbe613f285426a22de633af9f8593a332042eb Mon Sep 17 00:00:00 2001 From: ubadineke Date: Mon, 16 Sep 2024 07:20:03 +0100 Subject: [PATCH 1/4] changed return type and added extra code for revoke delegates --- .../tokens-and-nfts/token-program-advanced.md | 55 +++++++++++++++---- 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/content/courses/tokens-and-nfts/token-program-advanced.md b/content/courses/tokens-and-nfts/token-program-advanced.md index 16c827c38..aef1a6c4a 100644 --- a/content/courses/tokens-and-nfts/token-program-advanced.md +++ b/content/courses/tokens-and-nfts/token-program-advanced.md @@ -51,7 +51,7 @@ Under the hood, the `burn` function creates a transaction with instructions obtained from the `createBurnInstruction` function: ```typescript -import { PublicKey, Transaction } from "@solana/web3"; +import { PublicKey, Transaction } from "@solana/web3.js"; import { createBurnInstruction } from "@solana/spl-token"; async function buildBurnTransaction( @@ -105,7 +105,7 @@ Under the hood, the `approve` function creates a transaction with instructions obtained from the `createApproveInstruction` function: ```typescript -import { PublicKey, Transaction } from "@solana/web3"; +import { PublicKey, Transaction } from "@solana/web3.js"; import { createApproveInstruction } from "@solana/spl-token"; async function buildApproveTransaction( @@ -113,7 +113,7 @@ async function buildApproveTransaction( delegate: PublicKey, owner: PublicKey, amount: number, -): Promise { +): Promise { const transaction = new Transaction().add( createApproveInstruction(account, delegate, owner, amount), ); @@ -150,13 +150,13 @@ Under the hood, the `revoke` function creates a transaction with instructions obtained from the `createRevokeInstruction` function: ```typescript -import { PublicKey, Transaction } from "@solana/web3"; +import { PublicKey, Transaction } from "@solana/web3.js"; import { revoke } from "@solana/spl-token"; async function buildRevokeTransaction( account: PublicKey, owner: PublicKey, -): Promise { +): Promise { const transaction = new Transaction().add( createRevokeInstruction(account, owner), ); @@ -231,7 +231,7 @@ const approveTransactionSignature = await approve( ); console.log( - `Approve Delegate Transaction: ${getExplorerLink( + ✅`Approve Delegate Transaction: ${getExplorerLink( "transaction", approveTransactionSignature, "devnet", @@ -243,12 +243,47 @@ console.log( Lets revoke the `delegate` using the `spl-token` library's `revoke` function. -Revoke will set delegate for the token account to null and reset the delegated +Revoke will set delegate for the associated token account to null and reset the delegated amount to 0. -All we will need for this function is the token account and user. After the +Create a new file `revoke-token.ts` + ```typescript +import "dotenv/config"; +import { + getExplorerLink, + getKeypairFromEnvironment, +} from "@solana-developers/helpers"; +import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js"; +import { + approve, + getOrCreateAssociatedTokenAccount, + revoke, +} from "@solana/spl-token"; + +const connection = new Connection(clusterApiUrl("devnet")); + +const user = getKeypairFromEnvironment("SECRET_KEY"); + +console.log( + `🔑 Loaded our keypair securely, using an env file! Our public key is: ${user.publicKey.toBase58()}`, +); + +// Add the delegate public key here. +const delegate = new PublicKey("YOUR_DELEGATE_HERE"); + +// Substitute in your token mint account +const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); + +// Get or create the source and destination token accounts to store this token +const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( + connection, + user, + tokenMintAccount, + user.publicKey, +); + const revokeTransactionSignature = await revoke( connection, user, @@ -257,7 +292,7 @@ const revokeTransactionSignature = await revoke( ); console.log( - `Revoke Delegate Transaction: ${getExplorerLink( + ✅`Revoke Delegate Transaction: ${getExplorerLink( "transaction", revokeTransactionSignature, "devnet", @@ -315,7 +350,7 @@ const transactionSignature = await burn( ); console.log( - `Burn Transaction: ${getExplorerLink( + ✅`Burn Transaction: ${getExplorerLink( "transaction", transactionSignature, "devnet", From 45c71c58578123844b801828454c00db2c81d053 Mon Sep 17 00:00:00 2001 From: ubadineke Date: Mon, 16 Sep 2024 14:37:22 +0100 Subject: [PATCH 2/4] added top async function and explorer links to view transactions --- .../tokens-and-nfts/token-program-advanced.md | 155 ++++++++++-------- 1 file changed, 87 insertions(+), 68 deletions(-) diff --git a/content/courses/tokens-and-nfts/token-program-advanced.md b/content/courses/tokens-and-nfts/token-program-advanced.md index aef1a6c4a..c9875bb8c 100644 --- a/content/courses/tokens-and-nfts/token-program-advanced.md +++ b/content/courses/tokens-and-nfts/token-program-advanced.md @@ -210,35 +210,41 @@ const delegate = new PublicKey("YOUR_DELEGATE_HERE"); // Substitute in your token mint account const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); -// Get or create the source and destination token accounts to store this token -const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( - connection, - user, - tokenMintAccount, - user.publicKey, -); +(async () => { + // Get or create the source and destination token accounts to store this token + const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( + connection, + user, + tokenMintAccount, + user.publicKey, + ); -// Our token has two decimal places -const MINOR_UNITS_PER_MAJOR_UNITS = Math.pow(10, 2); + // Our token has two decimal places + const MINOR_UNITS_PER_MAJOR_UNITS = Math.pow(10, 2); -const approveTransactionSignature = await approve( - connection, - user, - sourceTokenAccount.address, - delegate, - user.publicKey, - 50 * MINOR_UNITS_PER_MAJOR_UNITS, -); + const approveTransactionSignature = await approve( + connection, + user, + sourceTokenAccount.address, + delegate, + user.publicKey, + 50 * MINOR_UNITS_PER_MAJOR_UNITS, + ); -console.log( - ✅`Approve Delegate Transaction: ${getExplorerLink( - "transaction", - approveTransactionSignature, - "devnet", - )}`, -); + console.log( + ✅`Approve Delegate Transaction: ${getExplorerLink( + "transaction", + approveTransactionSignature, + "devnet", + )}`, + ); +})(); ``` +Run the script using `npx esrun delegate-tokens.ts`. You should see: +```bash +✅ Approve Delegate Transaction: https://explorer.solana.com/tx/31zsmGuX3NM1ip88mowaHT8B3gKDET3b6QnWSRcs2oWXeu9hgGoJunKmbTXZPF1cjpk2aaymf1wuBn58gAp5Q2h?cluster=devnet +``` #### 2. Revoke Delegate Lets revoke the `delegate` using the `spl-token` library's `revoke` function. @@ -276,28 +282,35 @@ const delegate = new PublicKey("YOUR_DELEGATE_HERE"); // Substitute in your token mint account const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); -// Get or create the source and destination token accounts to store this token -const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( - connection, - user, - tokenMintAccount, - user.publicKey, -); +(async () => { + // Get or create the source and destination token accounts to store this token + const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( + connection, + user, + tokenMintAccount, + user.publicKey, + ); -const revokeTransactionSignature = await revoke( - connection, - user, - sourceTokenAccount.address, - user.publicKey, -); + const revokeTransactionSignature = await revoke( + connection, + user, + sourceTokenAccount.address, + user.publicKey, + ); -console.log( - ✅`Revoke Delegate Transaction: ${getExplorerLink( - "transaction", - revokeTransactionSignature, - "devnet", - )}`, -); + console.log( + ✅`Revoke Delegate Transaction: ${getExplorerLink( + "transaction", + revokeTransactionSignature, + "devnet", + )}`, + ); +})(); +``` +Run the script using `npx esrun revoke-tokens.ts`. You should see: + +```bash +✅ Revoke Delegate Transaction: https://explorer.solana.com/tx/2jFgvXeF19nSFzjGLVoKo8vtGBp7xan3UZkRaGEpXHCuhKYerEiaE6a4oWVvJXjjYLNmt76XSx5U23J89moma31H?cluster=devnet ``` #### 3. Burn Tokens @@ -307,7 +320,7 @@ Finally, let's remove some tokens from circulation by burning them. Use the `spl-token` library's `burn` function to remove half of your tokens from circulation. -Now call this new function in `main` to burn 25 of the user's tokens. +Create a new file `burn-tokens.ts` ```typescript import "dotenv/config"; @@ -330,34 +343,40 @@ console.log( const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); // Get the account where the user stores these tokens -const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( - connection, - user, - tokenMintAccount, - user.publicKey, -); +(async () => { + const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( + connection, + user, + tokenMintAccount, + user.publicKey, + ); -// Our token has two decimal places -const MINOR_UNITS_PER_MAJOR_UNITS = Math.pow(10, 2); + // Our token has two decimal places + const MINOR_UNITS_PER_MAJOR_UNITS = Math.pow(10, 2); -const transactionSignature = await burn( - connection, - user, - sourceTokenAccount.address, - tokenMintAccount, - user, - 25 * MINOR_UNITS_PER_MAJOR_UNITS, -); + const transactionSignature = await burn( + connection, + user, + sourceTokenAccount.address, + tokenMintAccount, + user, + 25 * MINOR_UNITS_PER_MAJOR_UNITS, + ); -console.log( - ✅`Burn Transaction: ${getExplorerLink( - "transaction", - transactionSignature, - "devnet", - )}`, -); + console.log( + ✅`Burn Transaction: ${getExplorerLink( + "transaction", + transactionSignature, + "devnet", + )}`, + ); +})(); ``` +Run the script using `npx esrun burn-tokens.ts`. You should see: +```bash +✅ Burn Transaction: https://explorer.solana.com/tx/29jRrkMsnibmW5tNaxv38bZDe2QioZMeAurPdMvdZiqVA6biwYFcn5wGFgm6YC7bAwBufZFhXz4kh9Avsh1Ggn3u?cluster=devnet +``` Well done! You've now From 45df831417f5167e522935e0caddbfbc0c6dbfcd Mon Sep 17 00:00:00 2001 From: ubadineke Date: Mon, 16 Sep 2024 16:38:43 +0100 Subject: [PATCH 3/4] fixed prettier issue --- .../tokens-and-nfts/token-program-advanced.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/content/courses/tokens-and-nfts/token-program-advanced.md b/content/courses/tokens-and-nfts/token-program-advanced.md index c9875bb8c..baa3bad5f 100644 --- a/content/courses/tokens-and-nfts/token-program-advanced.md +++ b/content/courses/tokens-and-nfts/token-program-advanced.md @@ -240,21 +240,22 @@ const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); ); })(); ``` -Run the script using `npx esrun delegate-tokens.ts`. You should see: + +Run the script using `npx esrun delegate-tokens.ts`. You should see: ```bash ✅ Approve Delegate Transaction: https://explorer.solana.com/tx/31zsmGuX3NM1ip88mowaHT8B3gKDET3b6QnWSRcs2oWXeu9hgGoJunKmbTXZPF1cjpk2aaymf1wuBn58gAp5Q2h?cluster=devnet ``` + #### 2. Revoke Delegate Lets revoke the `delegate` using the `spl-token` library's `revoke` function. -Revoke will set delegate for the associated token account to null and reset the delegated -amount to 0. +Revoke will set delegate for the associated token account to null and reset the +delegated amount to 0. Create a new file `revoke-token.ts` - ```typescript import "dotenv/config"; import { @@ -307,7 +308,8 @@ const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); ); })(); ``` -Run the script using `npx esrun revoke-tokens.ts`. You should see: + +Run the script using `npx esrun revoke-tokens.ts`. You should see: ```bash ✅ Revoke Delegate Transaction: https://explorer.solana.com/tx/2jFgvXeF19nSFzjGLVoKo8vtGBp7xan3UZkRaGEpXHCuhKYerEiaE6a4oWVvJXjjYLNmt76XSx5U23J89moma31H?cluster=devnet @@ -372,11 +374,13 @@ const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); ); })(); ``` -Run the script using `npx esrun burn-tokens.ts`. You should see: + +Run the script using `npx esrun burn-tokens.ts`. You should see: ```bash ✅ Burn Transaction: https://explorer.solana.com/tx/29jRrkMsnibmW5tNaxv38bZDe2QioZMeAurPdMvdZiqVA6biwYFcn5wGFgm6YC7bAwBufZFhXz4kh9Avsh1Ggn3u?cluster=devnet ``` + Well done! You've now From 3ebd112e1613cc7cc949165b75e722e7dcdf038e Mon Sep 17 00:00:00 2001 From: ubadineke Date: Tue, 17 Sep 2024 07:44:15 +0100 Subject: [PATCH 4/4] removed top level async and added filename info --- .../tokens-and-nfts/token-program-advanced.md | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/content/courses/tokens-and-nfts/token-program-advanced.md b/content/courses/tokens-and-nfts/token-program-advanced.md index baa3bad5f..4ac7d3084 100644 --- a/content/courses/tokens-and-nfts/token-program-advanced.md +++ b/content/courses/tokens-and-nfts/token-program-advanced.md @@ -183,7 +183,7 @@ if you like, or find a friend who has a devnet account! Create a new file `delegate-tokens.ts` -```typescript +```typescript filename="delegate-tokens.ts" import "dotenv/config"; import { getExplorerLink, @@ -210,7 +210,6 @@ const delegate = new PublicKey("YOUR_DELEGATE_HERE"); // Substitute in your token mint account const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); -(async () => { // Get or create the source and destination token accounts to store this token const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( connection, @@ -238,7 +237,6 @@ const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); "devnet", )}`, ); -})(); ``` Run the script using `npx esrun delegate-tokens.ts`. You should see: @@ -256,7 +254,7 @@ delegated amount to 0. Create a new file `revoke-token.ts` -```typescript +```typescript filename="revoke-token.ts" import "dotenv/config"; import { getExplorerLink, @@ -283,7 +281,6 @@ const delegate = new PublicKey("YOUR_DELEGATE_HERE"); // Substitute in your token mint account const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); -(async () => { // Get or create the source and destination token accounts to store this token const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( connection, @@ -306,7 +303,6 @@ const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); "devnet", )}`, ); -})(); ``` Run the script using `npx esrun revoke-tokens.ts`. You should see: @@ -324,7 +320,7 @@ circulation. Create a new file `burn-tokens.ts` -```typescript +```typescript filename="burn-tokens.ts" import "dotenv/config"; import { getExplorerLink, @@ -345,7 +341,6 @@ console.log( const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); // Get the account where the user stores these tokens -(async () => { const sourceTokenAccount = await getOrCreateAssociatedTokenAccount( connection, user, @@ -372,7 +367,6 @@ const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE"); "devnet", )}`, ); -})(); ``` Run the script using `npx esrun burn-tokens.ts`. You should see: