createAndMint.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /**
  2. Overall flow of this script
  3. - load or create two keypairs (named `payer` and `testWallet`)
  4. - create a new tree with enough space to mint all the nft's you want for the "collection"
  5. - create a new NFT Collection on chain (using the usual Metaplex methods)
  6. - mint a single compressed nft into the tree to the `payer`
  7. - mint a single compressed nft into the tree to the `testWallet`
  8. - display the overall cost to perform all these actions
  9. ---
  10. NOTE: this script is identical to the `scripts/verboseCreateAndMint.ts` file, except THIS file has
  11. less console logging and explanation of what is occurring
  12. */
  13. import { Keypair, LAMPORTS_PER_SOL, clusterApiUrl } from "@solana/web3.js";
  14. import {
  15. MetadataArgs,
  16. TokenProgramVersion,
  17. TokenStandard,
  18. } from "@metaplex-foundation/mpl-bubblegum";
  19. // import custom helpers to mint compressed NFTs
  20. import {
  21. createCollection,
  22. createTree,
  23. mintCompressedNFT,
  24. } from "./utils/compression";
  25. // import custom helpers for demos
  26. import { loadKeypairFromFile, numberFormatter } from "./utils/helpers";
  27. import { CreateMetadataAccountArgsV3 } from "@metaplex-foundation/mpl-token-metadata";
  28. import { ValidDepthSizePair } from "@solana/spl-account-compression";
  29. // local import of the connection wrapper, to help with using the ReadApi
  30. import { WrapperConnection } from "./ReadApi/WrapperConnection";
  31. import { RPC_PATH } from "./cnft-burn";
  32. import * as anchor from "@coral-xyz/anchor";
  33. // define some reusable balance values for tracking
  34. let initBalance: number, balance: number;
  35. export async function createAndMint() {
  36. //////////////////////////////////////////////////////////////////////////////
  37. //////////////////////////////////////////////////////////////////////////////
  38. // load it locally from the filesystem when available
  39. anchor.setProvider(anchor.AnchorProvider.env());
  40. const provider = anchor.AnchorProvider.env();
  41. const payerWallet = provider.wallet as anchor.Wallet;
  42. const payer = payerWallet.payer;
  43. console.log("Payer address:", payer.publicKey.toBase58());
  44. //////////////////////////////////////////////////////////////////////////////
  45. //////////////////////////////////////////////////////////////////////////////
  46. // load the env variables and store the cluster RPC url
  47. const CLUSTER_URL = RPC_PATH;
  48. // create a new rpc connection, using the ReadApi wrapper
  49. const connection = new WrapperConnection(CLUSTER_URL, "confirmed");
  50. // get the payer's starting balance (only used for demonstration purposes)
  51. initBalance = await connection.getBalance(payer.publicKey);
  52. //////////////////////////////////////////////////////////////////////////////
  53. //////////////////////////////////////////////////////////////////////////////
  54. /*
  55. Define our tree size parameters
  56. */
  57. const maxDepthSizePair: ValidDepthSizePair = {
  58. // max=16,384 nodes
  59. maxDepth: 14,
  60. maxBufferSize: 64,
  61. };
  62. const canopyDepth = maxDepthSizePair.maxDepth - 5;
  63. /*
  64. Actually allocate the tree on chain
  65. */
  66. // define the address the tree will live at
  67. const treeKeypair = Keypair.generate();
  68. // create and send the transaction to create the tree on chain
  69. const tree = await createTree(
  70. connection,
  71. payer,
  72. treeKeypair,
  73. maxDepthSizePair,
  74. canopyDepth
  75. );
  76. /*
  77. Create the actual NFT collection (using the normal Metaplex method)
  78. (nothing special about compression here)
  79. */
  80. // define the metadata to be used for creating the NFT collection
  81. const collectionMetadataV3: CreateMetadataAccountArgsV3 = {
  82. data: {
  83. name: "Test Burn",
  84. symbol: "TB",
  85. // specific json metadata for the collection
  86. uri: "https://supersweetcollection.notarealurl/collection.json",
  87. sellerFeeBasisPoints: 100,
  88. creators: [
  89. {
  90. address: payer.publicKey,
  91. verified: false,
  92. share: 100,
  93. },
  94. ],
  95. collection: null,
  96. uses: null,
  97. },
  98. isMutable: false,
  99. collectionDetails: null,
  100. };
  101. // create a full token mint and initialize the collection (with the `payer` as the authority)
  102. const collection = await createCollection(
  103. connection,
  104. payer,
  105. collectionMetadataV3
  106. );
  107. /*
  108. Mint a single compressed NFT
  109. */
  110. const compressedNFTMetadata: MetadataArgs = {
  111. name: "Pratik test",
  112. symbol: collectionMetadataV3.data.symbol,
  113. // specific json metadata for each NFT
  114. uri: "https://bafkreies5r7b5eszpq5dgnw2brhjtlw7xtdtmsmoniebqehf37nv5rxajy.ipfs.nftstorage.link/",
  115. creators: [
  116. {
  117. address: payer.publicKey,
  118. verified: false,
  119. share: 100,
  120. },
  121. ],
  122. editionNonce: 0,
  123. uses: null,
  124. collection: null,
  125. primarySaleHappened: false,
  126. sellerFeeBasisPoints: 0,
  127. isMutable: false,
  128. // these values are taken from the Bubblegum package
  129. tokenProgramVersion: TokenProgramVersion.Original,
  130. tokenStandard: TokenStandard.NonFungible,
  131. };
  132. // fully mint a single compressed NFT to the payer
  133. console.log(
  134. `Minting a single compressed NFT to ${payer.publicKey.toBase58()}...`
  135. );
  136. await mintCompressedNFT(
  137. connection,
  138. payer,
  139. treeKeypair.publicKey,
  140. collection.mint,
  141. collection.metadataAccount,
  142. collection.masterEditionAccount,
  143. compressedNFTMetadata,
  144. // mint to this specific wallet (in this case, the tree owner aka `payer`)
  145. payer.publicKey
  146. );
  147. //////////////////////////////////////////////////////////////////////////////
  148. //////////////////////////////////////////////////////////////////////////////
  149. // fetch the payer's final balance
  150. balance = await connection.getBalance(payer.publicKey);
  151. console.log(`===============================`);
  152. console.log(
  153. "Total cost:",
  154. numberFormatter((initBalance - balance) / LAMPORTS_PER_SOL, true),
  155. "SOL\n"
  156. );
  157. return { tree, collection };
  158. }