{"id":22399894,"url":"https://github.com/laugharne/ssf_s2_exo","last_synced_at":"2025-07-05T19:02:27.823Z","repository":{"id":251538649,"uuid":"837627902","full_name":"Laugharne/ssf_s2_exo","owner":"Laugharne","description":"Build a web UI that can handle creation of a token, it's mint, transfer of that token, burning the token supply, and delegation the ata of this token to another public key.","archived":false,"fork":false,"pushed_at":"2024-08-04T11:02:07.000Z","size":956,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T00:16:57.970Z","etag":null,"topics":["fellowship","nextjs","solana","spl-token","summer","typescript"],"latest_commit_sha":null,"homepage":"https://ssf-s2-exo.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Laugharne.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-03T14:33:51.000Z","updated_at":"2024-08-04T11:02:10.000Z","dependencies_parsed_at":"2024-08-03T20:29:33.157Z","dependency_job_id":"550231e3-2ff4-459c-9882-8fd45b2305fc","html_url":"https://github.com/Laugharne/ssf_s2_exo","commit_stats":null,"previous_names":["laugharne/ssf_s2_exo"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Laugharne/ssf_s2_exo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Fssf_s2_exo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Fssf_s2_exo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Fssf_s2_exo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Fssf_s2_exo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Laugharne","download_url":"https://codeload.github.com/Laugharne/ssf_s2_exo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Laugharne%2Fssf_s2_exo/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263789900,"owners_count":23511892,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fellowship","nextjs","solana","spl-token","summer","typescript"],"created_at":"2024-12-05T08:10:25.967Z","updated_at":"2025-07-05T19:02:27.764Z","avatar_url":"https://github.com/Laugharne.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# solana-web3-next\n\n## Vercel Link \n\n**[solana-web3-next](https://ssf-s2-exo.vercel.app/)**\n\n## Overview\n\n![](2024-08-04-08-26-31.png)\n\n**Exercise:** Build a **web UI** that can handle creation of a token, it's mint, transfer of that token, burning the token supply, and delegation the ata of this token to another public key.\n\nTopics in this exercice:\n- Keypair generation\n- Airdrop\n- Mint account creation\n- ATA creation\n- Token mint operation\n- Token balance\n- Token transfer\n- Token burning\n- Authority delegation\n- Token transfer via delagation\n\nThis project is generated with the [create-solana-dapp](https://github.com/solana-developers/create-solana-dapp) generator.\n\nAnd deployed on Vercel : [solana-web3-next](https://ssf-s2-exo.vercel.app/)\n\n## Tree repository\n\n```\n.\n├── web\n│   ├── app\n│   │   ├── account\n│   │   │   ├── [address]\n│   │   │   │   └── page.tsx\n│   │   │   └── page.tsx\n│   │   ├── api\n│   │   │   └── hello\n│   │   │       └── route.ts\n│   │   ├── clusters\n│   │   │   └── page.tsx\n│   │   ├── global.css\n│   │   ├── layout.tsx\n│   │   ├── page.module.css\n│   │   ├── page.tsx\n│   │   └── react-query-provider.tsx\n│   ├── components\n│   │   ├── account\n│   │   │   ├── account-data-access.tsx\n│   │   │   ├── account-detail-feature.tsx\n│   │   │   ├── account-list-feature.tsx\n│   │   │   └── account-ui.tsx\n│   │   ├── cluster\n│   │   │   ├── cluster-data-access.tsx\n│   │   │   ├── cluster-feature.tsx\n│   │   │   └── cluster-ui.tsx\n│   │   ├── dashboard\n│   │   │   └── dashboard-feature.tsx\n│   │   ├── solana\n│   │   │   └── solana-provider.tsx\n│   │   └── ui\n│   │       └── ui-layout.tsx\n│   ├── public\n│   │   ├── favicon.ico\n│   │   └── logo.png\n│   ├── index.d.ts\n│   ├── next.config.js\n│   ├── next-env.d.ts\n│   ├── postcss.config.js\n│   ├── project.json\n│   ├── tailwind.config.js\n│   └── tsconfig.json\n├── 2024-08-04-08-26-31.png\n├── LICENSE\n├── nx.json\n├── package.json\n├── package-lock.json\n├── README.md\n├── tsconfig.base.json\n└── vercel.json\n```\n## Usage with screenshots\n\n### Accounts created (+airdrop)\n![](2024-08-04-08-33-40.png)\n\n### Token account created\n![](2024-08-04-08-33-52.png)\n\n### Tokens minted\n![](2024-08-04-08-34-11.png)\n\n### Token transfer\n![](2024-08-04-08-34-23.png)\n\n### Token burning\n![](2024-08-04-08-34-31.png)\n\n### Delegation\n![](2024-08-04-08-34-45.png)\n\n### Transfer via delegation\n![](2024-08-04-08-34-57.png)\n\n## Code snippets\n\n### bla\n```typescript\n\n```\n\n### Keypair generation + airdrop\n```typescript\nconst newPayer = await Keypair.generate();\nconsole.log(\"mainInit (payer)\"+newPayer.publicKey.toBase58());\n\nconst airdropSignature = await connection.requestAirdrop(newPayer.publicKey, 2 * LAMPORTS_PER_SOL);\nconnection.confirmTransaction(airdropSignature).then(()=\u003e {\n    setPayer(newPayer);\n    setAidropTx(airdropSignature);\n})\n```\n### Mint account creation\n```typescript\nlet newMintPubkey = await createMint(\n  connection      ,   // connection\n  payer           ,   // fee payer\n  payer.publicKey,    // mint authority\n  null           ,    // freeze authority (you can use `null` to disable it. when you disable it, you can't turn it on again)\n  decimals       ,    // decimals\n);\n\nconsole.log(newMintPubkey.toBase58());\n\n```\n\n### ATA creation\n```typescript\nconst newTokenAccount = await getOrCreateAssociatedTokenAccount(\n  connection,\n  payer,\n  newMintPubkey,\n  payer.publicKey\n);\n\nconsole.log(\"Token Account\");\nconsole.log(\"ATA\", newTokenAccount.address.toBase58());\n\n```\n\n### Token mint operation\n```typescript\nlet mintTx = await mintTo(\n  connection          ,            // connection\n  payer               ,            // payer\n  mintPubkey          ,            // mint\n  tokenAccount.address,            // destination\n  payer.publicKey     ,            // authority\n  mintAmount                       // amount\n);\nconsole.log('Mint Transaction:', mintTx);\n\n\nawait setAuthority(\n  connection,\n  payer          ,      // Payer of the transaction fees\n  mintPubkey     ,      // Account \n  payer.publicKey,      // Current authority \n  0              ,      // Authority type: \"0\" represents Mint Tokens \n  null                  // Setting the new Authority to null\n);\nconsole.log('Authority is set !');\n```\n\n### Token balance\n```typescript\nconst tokenAccountInfo = await getAccount(\n  connection,\n  tokenAccount.address\n);\nconsole.log('Token Account Info:', tokenAccountInfo.amount);\nconst newBalanceToken = tokenAccountInfo.amount / BigInt(Math.pow(10, decimals));\nconsole.log(newBalanceToken);\n\n```\n\n### Token transfer\n```typescript\n// Get the token account of the toWallet Solana address. If it does not exist, create it.\nconst toATA = await getOrCreateAssociatedTokenAccount(\n  connection,\n  payer,\n  mintPubkey,\n  pk\n);\nconsole.log(\"Token Account\");\nconsole.log(\"ATA (to)\", toATA.address.toBase58());\n\nlet tx = await transfer(\n  connection          ,                // connection\n  payer               ,                // payer\n  tokenAccount.address,                // source account\n  toATA.address       ,                // destination account\n  payer.publicKey     ,                // destination **\n  amount*Math.pow     (10,decimals),   // amount\n);\n\n```\n\n### Token burning\n```typescript\nconst newBurnSignature = await burn(\n  connection,\n  payer                ,   // Payer of the transaction fees\n  tokenAccount.address,    // Address of the account holding the tokens to burn\n  mintPubkey           ,   // Mint of the token\n  payer.publicKey      ,   // Owner of the account\n  burnAmount*Math.pow(10,decimals)          ,    // Amount of tokens to burn\n);\n```\n\n### Authority delegation\n```typescript\nconst pk = new PublicKey(delegation);\nconsole.log(pk.toBase58()); // Affiche l'objet PublicKey,puis en base58\n\nconst approveSignature = await approve(\n  connection,\n  payer,                // Payer of the transaction fees\n  tokenAccount.address, // Account from which tokens can be transferred\n  pk,                   // Delegate authority\n  payer.publicKey,      // Owner of the token account\n  delegateAmount*Math.pow(10,decimals)            // Amount of tokens the delegate is allowed to transfer\n);\nconsole.log(\"Delegation\");\nconsole.log(approveSignature);\n```\n\n\n### Token transfer via delagation\n```typescript\nconst pkDelegation = new PublicKey(delegation);\nconsole.log(pkDelegation.toBase58());\nconst pkDestination = new PublicKey(destination);\nconsole.log(pkDestination.toBase58());\n\n// Get the token account of the toWallet Solana address. If it does not exist, create it.\nconst toATA = await getOrCreateAssociatedTokenAccount(\n  connection,\n  payer,\n  mintPubkey,\n  pkDestination\n);\nconsole.log(\"Token Account\");\nconsole.log(\"ATA (to)\", toATA.address.toBase58());\n\nconst delegateTransferAmount = 1;\n\nconst delegateTransferSignature = await transfer(\n  connection,\n  delegationWallet,      // Payer of the transaction fees X\n  tokenAccount.address,  // Source account X\n  toATA.address,         // Destination account X\n  pkDelegation,          // Delegated authority\n  delegateTransferAmount*Math.pow(10,decimals)     // Number of tokens to transfer\n);\nconsole.log(\"Delegate Transfer Signature:\", delegateTransferSignature);\n\n```\n## Resources\n\n- [GitHub - anza-xyz/wallet-adapter: Modular TypeScript wallet adapters and components for Solana applications.](https://github.com/anza-xyz/wallet-adapter)\n- [Interacting with Tokens | Solana Cookbook](https://solanacookbook.com/references/token.html#what-do-i-need-to-get-started-with-spl-tokens)\n- [Sending Transactions | Solana Cookbook](https://solanacookbook.com/references/basic-transactions.html#how-to-send-spl-tokens) (_Click on Wallet Adapter, and the dev icon_) \n- [How to Mint an NFT on Solana](https://medium.com/@accesstoarpan/how-to-mint-an-nft-on-solana-77a38353fbdf)\n- [creating tokens on solana](https://3illbaby.hashnode.dev/how-to-create-tokens-on-solana-in-2024-a-developers-step-by-step-guide#heading-summary)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaugharne%2Fssf_s2_exo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flaugharne%2Fssf_s2_exo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flaugharne%2Fssf_s2_exo/lists"}