createAndMint.ts 5.6 KB

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