mpl_metadata.sol 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. import 'solana';
  2. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/instruction/metadata.rs#L449
  3. // Solidity does not support Rust Option<> type, so we need to handle it manually
  4. // Requires creating a struct for each combination of Option<> types
  5. // If bool for Option<> type is false, comment out the corresponding struct field otherwise instruction fails with "invalid account data"
  6. // TODO: figure out better way to handle Option<> types
  7. library MplMetadata {
  8. address constant systemAddress = address"11111111111111111111111111111111";
  9. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/instruction/metadata.rs#L31
  10. struct CreateMetadataAccountArgsV3 {
  11. DataV2 data;
  12. bool isMutable;
  13. bool collectionDetailsPresent; // To handle Rust Option<> in Solidity
  14. // CollectionDetails collectionDetails;
  15. }
  16. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/state/data.rs#L22
  17. struct DataV2 {
  18. string name;
  19. string symbol;
  20. string uri;
  21. uint16 sellerFeeBasisPoints;
  22. bool creatorsPresent; // To handle Rust Option<> in Solidity
  23. // Creator[] creators;
  24. bool collectionPresent; // To handle Rust Option<> in Solidity
  25. // Collection collection;
  26. bool usesPresent; // To handle Rust Option<> in Solidity
  27. // Uses uses;
  28. }
  29. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L10
  30. struct Creator {
  31. address creatorAddress;
  32. bool verified;
  33. uint8 share;
  34. }
  35. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L66
  36. struct Collection {
  37. bool verified;
  38. address key;
  39. }
  40. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/token-metadata/program/src/state/collection.rs#L57
  41. struct CollectionDetails {
  42. CollectionDetailsType detailType;
  43. uint64 size;
  44. }
  45. enum CollectionDetailsType {
  46. V1
  47. }
  48. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L43
  49. struct Uses {
  50. UseMethod useMethod;
  51. uint64 remaining;
  52. uint64 total;
  53. }
  54. // Reference: https://github.com/metaplex-foundation/metaplex-program-library/blob/master/bubblegum/program/src/state/metaplex_adapter.rs#L35
  55. enum UseMethod {
  56. Burn,
  57. Multiple,
  58. Single
  59. }
  60. function create_metadata_account(
  61. address metadata,
  62. address mint,
  63. address mintAuthority,
  64. address payer,
  65. address updateAuthority,
  66. string name,
  67. string symbol,
  68. string uri,
  69. address metadataProgramId,
  70. address rentAddress
  71. ) public {
  72. // // Example of how to add a Creator[] array to the DataV2 struct
  73. // Creator[] memory creators = new Creator[](1);
  74. // creators[0] = Creator({
  75. // creatorAddress: payer,
  76. // verified: false,
  77. // share: 100
  78. // });
  79. DataV2 data = DataV2({
  80. name: name,
  81. symbol: symbol,
  82. uri: uri,
  83. sellerFeeBasisPoints: 0,
  84. creatorsPresent: false,
  85. // creators: creators,
  86. collectionPresent: false,
  87. // collection: Collection({
  88. // verified: false,
  89. // key: address(0)
  90. // }),
  91. usesPresent: false
  92. // uses: Uses({
  93. // useMethod: UseMethod.Burn,
  94. // remaining: 0,
  95. // total: 0
  96. // })
  97. });
  98. CreateMetadataAccountArgsV3 args = CreateMetadataAccountArgsV3({
  99. data: data,
  100. isMutable: true,
  101. collectionDetailsPresent: false
  102. // collectionDetails: CollectionDetails({
  103. // detailType: CollectionDetailsType.V1,
  104. // size: 0
  105. // })
  106. });
  107. AccountMeta[7] metas = [
  108. AccountMeta({pubkey: metadata, is_writable: true, is_signer: false}),
  109. AccountMeta({pubkey: mint, is_writable: false, is_signer: false}),
  110. AccountMeta({pubkey: mintAuthority, is_writable: false, is_signer: true}),
  111. AccountMeta({pubkey: payer, is_writable: true, is_signer: true}),
  112. AccountMeta({pubkey: updateAuthority, is_writable: false, is_signer: false}),
  113. AccountMeta({pubkey: systemAddress, is_writable: false, is_signer: false}),
  114. AccountMeta({pubkey: rentAddress, is_writable: false, is_signer: false})
  115. ];
  116. bytes1 discriminator = 33;
  117. bytes instructionData = abi.encode(discriminator, args);
  118. metadataProgramId.call{accounts: metas}(instructionData);
  119. }
  120. }