createAndMint.ts 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. // define some reusable balance values for tracking
  33. let initBalance: number, balance: number;
  34. export async function createAndMint() {
  35. //////////////////////////////////////////////////////////////////////////////
  36. //////////////////////////////////////////////////////////////////////////////
  37. // generate a new keypair for use in this demo (or load it locally from the filesystem when available)
  38. const payer = loadKeypairFromFile("/Users/pratik/.config/solana/id.json");
  39. console.log("Payer address:", payer.publicKey.toBase58());
  40. //////////////////////////////////////////////////////////////////////////////
  41. //////////////////////////////////////////////////////////////////////////////
  42. // load the env variables and store the cluster RPC url
  43. const CLUSTER_URL = RPC_PATH;
  44. // create a new rpc connection, using the ReadApi wrapper
  45. const connection = new WrapperConnection(CLUSTER_URL, "confirmed");
  46. // get the payer's starting balance (only used for demonstration purposes)
  47. initBalance = await connection.getBalance(payer.publicKey);
  48. //////////////////////////////////////////////////////////////////////////////
  49. //////////////////////////////////////////////////////////////////////////////
  50. /*
  51. Define our tree size parameters
  52. */
  53. const maxDepthSizePair: ValidDepthSizePair = {
  54. // max=16,384 nodes
  55. maxDepth: 14,
  56. maxBufferSize: 64,
  57. };
  58. const canopyDepth = maxDepthSizePair.maxDepth - 5;
  59. /*
  60. Actually allocate the tree on chain
  61. */
  62. // define the address the tree will live at
  63. const treeKeypair = Keypair.generate();
  64. // create and send the transaction to create the tree on chain
  65. const tree = await createTree(
  66. connection,
  67. payer,
  68. treeKeypair,
  69. maxDepthSizePair,
  70. canopyDepth
  71. );
  72. /*
  73. Create the actual NFT collection (using the normal Metaplex method)
  74. (nothing special about compression here)
  75. */
  76. // define the metadata to be used for creating the NFT collection
  77. const collectionMetadataV3: CreateMetadataAccountArgsV3 = {
  78. data: {
  79. name: "Test Burn",
  80. symbol: "TB",
  81. // specific json metadata for the collection
  82. uri: "https://supersweetcollection.notarealurl/collection.json",
  83. sellerFeeBasisPoints: 100,
  84. creators: [
  85. {
  86. address: payer.publicKey,
  87. verified: false,
  88. share: 100,
  89. },
  90. ],
  91. collection: null,
  92. uses: null,
  93. },
  94. isMutable: false,
  95. collectionDetails: null,
  96. };
  97. // create a full token mint and initialize the collection (with the `payer` as the authority)
  98. const collection = await createCollection(
  99. connection,
  100. payer,
  101. collectionMetadataV3
  102. );
  103. /*
  104. Mint a single compressed NFT
  105. */
  106. const compressedNFTMetadata: MetadataArgs = {
  107. name: "Pratik test",
  108. symbol: collectionMetadataV3.data.symbol,
  109. // specific json metadata for each NFT
  110. uri: "https://bafkreies5r7b5eszpq5dgnw2brhjtlw7xtdtmsmoniebqehf37nv5rxajy.ipfs.nftstorage.link/",
  111. creators: [
  112. {
  113. address: payer.publicKey,
  114. verified: false,
  115. share: 100,
  116. },
  117. ],
  118. editionNonce: 0,
  119. uses: null,
  120. collection: null,
  121. primarySaleHappened: false,
  122. sellerFeeBasisPoints: 0,
  123. isMutable: false,
  124. // these values are taken from the Bubblegum package
  125. tokenProgramVersion: TokenProgramVersion.Original,
  126. tokenStandard: TokenStandard.NonFungible,
  127. };
  128. // fully mint a single compressed NFT to the payer
  129. console.log(
  130. `Minting a single compressed NFT to ${payer.publicKey.toBase58()}...`
  131. );
  132. await mintCompressedNFT(
  133. connection,
  134. payer,
  135. treeKeypair.publicKey,
  136. collection.mint,
  137. collection.metadataAccount,
  138. collection.masterEditionAccount,
  139. compressedNFTMetadata,
  140. // mint to this specific wallet (in this case, the tree owner aka `payer`)
  141. payer.publicKey
  142. );
  143. //////////////////////////////////////////////////////////////////////////////
  144. //////////////////////////////////////////////////////////////////////////////
  145. // fetch the payer's final balance
  146. balance = await connection.getBalance(payer.publicKey);
  147. console.log(`===============================`);
  148. console.log(
  149. "Total cost:",
  150. numberFormatter((initBalance - balance) / LAMPORTS_PER_SOL, true),
  151. "SOL\n"
  152. );
  153. return { tree, collection };
  154. }