compressed-nft.sol 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. import "solana";
  2. @program_id("BhDH6TLEnf4dLq9hLn2gLwm5rJdj8Cbdc9ZrsjUpL7kB")
  3. contract compressed_nft {
  4. @payer(payer) // payer address
  5. @seed("seed") // hardcoded seed
  6. constructor(
  7. @bump bytes1 bump // bump seed for pda address
  8. ) {
  9. // Creating a dataAccount for the program, which is required by Solang
  10. // However, this account is not used in the program
  11. }
  12. // Mint a compressed NFT to an existing merkle tree, via a cross-program invocation to the Bubblegum program
  13. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/lib.rs#L922
  14. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/lib.rs#L67
  15. function mint(
  16. address tree_authority, // authority of the merkle tree
  17. address leaf_owner, // owner of the new compressed NFT
  18. address leaf_delegate, // delegate of the new compressed NFT (can be the same as leaf_owner)
  19. address merkle_tree, // address of the merkle tree
  20. address payer, // payer
  21. address tree_delegate, // delegate of the merkle tree
  22. string uri // uri of the new compressed NFT (metadata)
  23. ) public {
  24. print("Minting Compressed NFT");
  25. // Create a creator array with a single creator
  26. Creator[] memory creators = new Creator[](1);
  27. // Set the creator to the payer
  28. creators[0] = Creator({
  29. creatorAddress: payer,
  30. verified: false,
  31. share: 100
  32. });
  33. // Create the metadata args, representing the metadata of the new compressed NFT
  34. // Solidity does not support optional arguments,
  35. // So we have to explicitly declare if the optional arguments are present or not
  36. // If not present, we comment them out, otherwise the transaction will fail with a invalid instruction data error
  37. MetadataArgs memory args = MetadataArgs({
  38. name: "RGB",
  39. symbol: "RGB",
  40. uri: uri,
  41. sellerFeeBasisPoints: 0,
  42. primarySaleHappened: false,
  43. isMutable: true,
  44. editionNoncePresent: false,
  45. // editionNonce: 0,
  46. tokenStandardPresent: true,
  47. tokenStandard: TokenStandard.NonFungible,
  48. collectionPresent: false,
  49. // collection: Collection({
  50. // verified: false,
  51. // key: address(0)
  52. // }),
  53. usesPresent: false,
  54. // uses: Uses({
  55. // useMethod: UseMethod.Burn,
  56. // remaining: 0,
  57. // total: 0
  58. // }),
  59. tokenProgramVersion: TokenProgramVersion.Original,
  60. creators: creators
  61. });
  62. AccountMeta[9] metas = [
  63. AccountMeta({pubkey: tree_authority, is_writable: true, is_signer: false}),
  64. AccountMeta({pubkey: leaf_owner, is_writable: false, is_signer: false}),
  65. AccountMeta({pubkey: leaf_delegate, is_writable: false, is_signer: false}),
  66. AccountMeta({pubkey: merkle_tree, is_writable: true, is_signer: false}),
  67. AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
  68. AccountMeta({pubkey: tree_delegate, is_writable: true, is_signer: true}),
  69. AccountMeta({pubkey: address"noopb9bkMVfRPU8AsbpTUg8AQkHtKwMYZiFUjNRtMmV", is_writable: false, is_signer: false}),
  70. AccountMeta({pubkey: address"cmtDvXumGCrqC1Age74AVPhSRVXJMd8PJS91L8KbNCK", is_writable: false, is_signer: false}),
  71. AccountMeta({pubkey: address"11111111111111111111111111111111", is_writable: false, is_signer: false})
  72. ];
  73. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/js/src/generated/instructions/mintV1.ts#L64
  74. bytes8 discriminator = 0x9162c076b8937668;
  75. bytes instructionData = abi.encode(discriminator, args);
  76. // Invoking the Bubblegum program
  77. address'BGUMAp9Gq7iTEuizy4pqaxsTyUCBK68MDfK752saRPUY'.call{accounts: metas}(instructionData);
  78. }
  79. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L81
  80. struct MetadataArgs {
  81. string name;
  82. string symbol;
  83. string uri;
  84. uint16 sellerFeeBasisPoints;
  85. bool primarySaleHappened;
  86. bool isMutable;
  87. bool editionNoncePresent;
  88. // uint8 editionNonce;
  89. bool tokenStandardPresent;
  90. TokenStandard tokenStandard;
  91. bool collectionPresent;
  92. // Collection collection;
  93. bool usesPresent;
  94. // Uses uses;
  95. TokenProgramVersion tokenProgramVersion;
  96. Creator[] creators;
  97. }
  98. enum TokenStandard {
  99. NonFungible,
  100. FungibleAsset,
  101. Fungible,
  102. NonFungibleEdition
  103. }
  104. enum TokenProgramVersion {
  105. Original,
  106. Token2022
  107. }
  108. struct Creator {
  109. address creatorAddress;
  110. bool verified;
  111. uint8 share;
  112. }
  113. struct Collection {
  114. bool verified;
  115. address key;
  116. }
  117. struct Uses {
  118. UseMethod useMethod;
  119. uint64 remaining;
  120. uint64 total;
  121. }
  122. enum UseMethod {
  123. Burn,
  124. Multiple,
  125. Single
  126. }
  127. }