metadata.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  1. use anchor_lang::context::CpiContext;
  2. use anchor_lang::error::ErrorCode;
  3. use anchor_lang::solana_program::account_info::AccountInfo;
  4. use anchor_lang::solana_program::pubkey::Pubkey;
  5. use anchor_lang::solana_program::sysvar;
  6. use anchor_lang::{system_program, Accounts, Result, ToAccountInfos};
  7. use std::ops::Deref;
  8. pub use mpl_token_metadata;
  9. pub use mpl_token_metadata::ID;
  10. pub fn approve_collection_authority<'info>(
  11. ctx: CpiContext<'_, '_, '_, 'info, ApproveCollectionAuthority<'info>>,
  12. ) -> Result<()> {
  13. let ix = mpl_token_metadata::instructions::ApproveCollectionAuthority {
  14. collection_authority_record: *ctx.accounts.collection_authority_record.key,
  15. metadata: *ctx.accounts.metadata.key,
  16. mint: *ctx.accounts.mint.key,
  17. new_collection_authority: *ctx.accounts.new_collection_authority.key,
  18. payer: *ctx.accounts.payer.key,
  19. rent: None,
  20. system_program: system_program::ID,
  21. update_authority: *ctx.accounts.update_authority.key,
  22. }
  23. .instruction();
  24. anchor_lang::solana_program::program::invoke_signed(
  25. &ix,
  26. &ToAccountInfos::to_account_infos(&ctx),
  27. ctx.signer_seeds,
  28. )
  29. .map_err(Into::into)
  30. }
  31. pub fn bubblegum_set_collection_size<'info>(
  32. ctx: CpiContext<'_, '_, '_, 'info, BubblegumSetCollectionSize<'info>>,
  33. collection_authority_record: Option<Pubkey>,
  34. size: u64,
  35. ) -> Result<()> {
  36. let ix = mpl_token_metadata::instructions::BubblegumSetCollectionSize {
  37. collection_metadata: *ctx.accounts.metadata_account.key,
  38. collection_authority: *ctx.accounts.update_authority.key,
  39. collection_mint: *ctx.accounts.mint.key,
  40. bubblegum_signer: *ctx.accounts.bubblegum_signer.key,
  41. collection_authority_record,
  42. }
  43. .instruction(
  44. mpl_token_metadata::instructions::BubblegumSetCollectionSizeInstructionArgs {
  45. set_collection_size_args: mpl_token_metadata::types::SetCollectionSizeArgs { size },
  46. },
  47. );
  48. anchor_lang::solana_program::program::invoke_signed(
  49. &ix,
  50. &ToAccountInfos::to_account_infos(&ctx),
  51. ctx.signer_seeds,
  52. )
  53. .map_err(Into::into)
  54. }
  55. pub fn burn_edition_nft<'info>(
  56. ctx: CpiContext<'_, '_, '_, 'info, BurnEditionNft<'info>>,
  57. ) -> Result<()> {
  58. let ix = mpl_token_metadata::instructions::BurnEditionNft {
  59. edition_marker_account: *ctx.accounts.edition_marker.key,
  60. master_edition_account: *ctx.accounts.master_edition.key,
  61. master_edition_mint: *ctx.accounts.master_edition_mint.key,
  62. master_edition_token_account: *ctx.accounts.master_edition_token.key,
  63. metadata: *ctx.accounts.metadata.key,
  64. owner: *ctx.accounts.owner.key,
  65. print_edition_account: *ctx.accounts.print_edition.key,
  66. print_edition_mint: *ctx.accounts.print_edition_mint.key,
  67. print_edition_token_account: *ctx.accounts.print_edition_token.key,
  68. spl_token_program: *ctx.accounts.spl_token.key,
  69. }
  70. .instruction();
  71. anchor_lang::solana_program::program::invoke_signed(
  72. &ix,
  73. &ToAccountInfos::to_account_infos(&ctx),
  74. ctx.signer_seeds,
  75. )
  76. .map_err(Into::into)
  77. }
  78. /// Burn an NFT by closing its token, metadata and edition accounts.
  79. ///
  80. /// The lamports of the closed accounts will be transferred to the owner.
  81. ///
  82. /// # Note
  83. ///
  84. /// This instruction takes an optional `collection_metadata` argument, if this argument is
  85. /// `Some`, the `ctx` argument should also include the `collection_metadata` account in its
  86. /// remaining accounts, otherwise the CPI will fail because [`BurnNft`] only includes required
  87. /// accounts.
  88. ///
  89. /// ```ignore
  90. /// CpiContext::new(program, BurnNft { .. })
  91. /// .with_remaining_accounts(vec![ctx.accounts.collection_metadata]);
  92. /// ```
  93. pub fn burn_nft<'info>(
  94. ctx: CpiContext<'_, '_, '_, 'info, BurnNft<'info>>,
  95. collection_metadata: Option<Pubkey>,
  96. ) -> Result<()> {
  97. let ix = mpl_token_metadata::instructions::BurnNft {
  98. collection_metadata,
  99. master_edition_account: *ctx.accounts.edition.key,
  100. metadata: *ctx.accounts.metadata.key,
  101. mint: *ctx.accounts.mint.key,
  102. owner: *ctx.accounts.owner.key,
  103. spl_token_program: *ctx.accounts.spl_token.key,
  104. token_account: *ctx.accounts.token.key,
  105. }
  106. .instruction();
  107. anchor_lang::solana_program::program::invoke_signed(
  108. &ix,
  109. &ToAccountInfos::to_account_infos(&ctx),
  110. ctx.signer_seeds,
  111. )
  112. .map_err(Into::into)
  113. }
  114. pub fn create_metadata_accounts_v3<'info>(
  115. ctx: CpiContext<'_, '_, '_, 'info, CreateMetadataAccountsV3<'info>>,
  116. data: mpl_token_metadata::types::DataV2,
  117. is_mutable: bool,
  118. update_authority_is_signer: bool,
  119. collection_details: Option<mpl_token_metadata::types::CollectionDetails>,
  120. ) -> Result<()> {
  121. let ix = mpl_token_metadata::instructions::CreateMetadataAccountV3 {
  122. metadata: *ctx.accounts.metadata.key,
  123. mint: *ctx.accounts.mint.key,
  124. mint_authority: *ctx.accounts.mint_authority.key,
  125. payer: *ctx.accounts.payer.key,
  126. rent: None,
  127. system_program: system_program::ID,
  128. update_authority: (
  129. *ctx.accounts.update_authority.key,
  130. update_authority_is_signer,
  131. ),
  132. }
  133. .instruction(
  134. mpl_token_metadata::instructions::CreateMetadataAccountV3InstructionArgs {
  135. collection_details,
  136. data,
  137. is_mutable,
  138. },
  139. );
  140. anchor_lang::solana_program::program::invoke_signed(
  141. &ix,
  142. &ToAccountInfos::to_account_infos(&ctx),
  143. ctx.signer_seeds,
  144. )
  145. .map_err(Into::into)
  146. }
  147. pub fn update_metadata_accounts_v2<'info>(
  148. ctx: CpiContext<'_, '_, '_, 'info, UpdateMetadataAccountsV2<'info>>,
  149. new_update_authority: Option<Pubkey>,
  150. data: Option<mpl_token_metadata::types::DataV2>,
  151. primary_sale_happened: Option<bool>,
  152. is_mutable: Option<bool>,
  153. ) -> Result<()> {
  154. let ix = mpl_token_metadata::instructions::UpdateMetadataAccountV2 {
  155. metadata: *ctx.accounts.metadata.key,
  156. update_authority: *ctx.accounts.update_authority.key,
  157. }
  158. .instruction(
  159. mpl_token_metadata::instructions::UpdateMetadataAccountV2InstructionArgs {
  160. new_update_authority,
  161. data,
  162. primary_sale_happened,
  163. is_mutable,
  164. },
  165. );
  166. anchor_lang::solana_program::program::invoke_signed(
  167. &ix,
  168. &ToAccountInfos::to_account_infos(&ctx),
  169. ctx.signer_seeds,
  170. )
  171. .map_err(Into::into)
  172. }
  173. pub fn create_master_edition_v3<'info>(
  174. ctx: CpiContext<'_, '_, '_, 'info, CreateMasterEditionV3<'info>>,
  175. max_supply: Option<u64>,
  176. ) -> Result<()> {
  177. let ix = mpl_token_metadata::instructions::CreateMasterEditionV3 {
  178. edition: *ctx.accounts.edition.key,
  179. metadata: *ctx.accounts.metadata.key,
  180. mint: *ctx.accounts.mint.key,
  181. mint_authority: *ctx.accounts.mint_authority.key,
  182. payer: *ctx.accounts.payer.key,
  183. rent: None,
  184. system_program: system_program::ID,
  185. token_program: spl_token::ID,
  186. update_authority: *ctx.accounts.update_authority.key,
  187. }
  188. .instruction(
  189. mpl_token_metadata::instructions::CreateMasterEditionV3InstructionArgs { max_supply },
  190. );
  191. anchor_lang::solana_program::program::invoke_signed(
  192. &ix,
  193. &ToAccountInfos::to_account_infos(&ctx),
  194. ctx.signer_seeds,
  195. )
  196. .map_err(Into::into)
  197. }
  198. pub fn mint_new_edition_from_master_edition_via_token<'info>(
  199. ctx: CpiContext<'_, '_, '_, 'info, MintNewEditionFromMasterEditionViaToken<'info>>,
  200. edition: u64,
  201. ) -> Result<()> {
  202. let ix = mpl_token_metadata::instructions::MintNewEditionFromMasterEditionViaToken {
  203. edition_mark_pda: *ctx.accounts.edition_mark_pda.key,
  204. master_edition: *ctx.accounts.master_edition.key,
  205. metadata: *ctx.accounts.metadata.key,
  206. new_edition: *ctx.accounts.new_edition.key,
  207. new_metadata: *ctx.accounts.new_metadata.key,
  208. new_metadata_update_authority: *ctx.accounts.new_metadata_update_authority.key,
  209. new_mint: *ctx.accounts.new_mint.key,
  210. new_mint_authority: *ctx.accounts.new_mint_authority.key,
  211. payer: *ctx.accounts.payer.key,
  212. rent: None,
  213. system_program: system_program::ID,
  214. token_account: *ctx.accounts.token_account.key,
  215. token_account_owner: *ctx.accounts.token_account_owner.key,
  216. token_program: spl_token::ID,
  217. }
  218. .instruction(
  219. mpl_token_metadata::instructions::MintNewEditionFromMasterEditionViaTokenInstructionArgs {
  220. mint_new_edition_from_master_edition_via_token_args:
  221. mpl_token_metadata::types::MintNewEditionFromMasterEditionViaTokenArgs { edition },
  222. },
  223. );
  224. anchor_lang::solana_program::program::invoke_signed(
  225. &ix,
  226. &ToAccountInfos::to_account_infos(&ctx),
  227. ctx.signer_seeds,
  228. )
  229. .map_err(Into::into)
  230. }
  231. pub fn revoke_collection_authority<'info>(
  232. ctx: CpiContext<'_, '_, '_, 'info, RevokeCollectionAuthority<'info>>,
  233. ) -> Result<()> {
  234. let ix = mpl_token_metadata::instructions::RevokeCollectionAuthority {
  235. collection_authority_record: *ctx.accounts.collection_authority_record.key,
  236. delegate_authority: *ctx.accounts.delegate_authority.key,
  237. metadata: *ctx.accounts.metadata.key,
  238. mint: *ctx.accounts.mint.key,
  239. revoke_authority: *ctx.accounts.revoke_authority.key,
  240. }
  241. .instruction();
  242. anchor_lang::solana_program::program::invoke_signed(
  243. &ix,
  244. &ToAccountInfos::to_account_infos(&ctx),
  245. ctx.signer_seeds,
  246. )
  247. .map_err(Into::into)
  248. }
  249. pub fn set_collection_size<'info>(
  250. ctx: CpiContext<'_, '_, '_, 'info, SetCollectionSize<'info>>,
  251. collection_authority_record: Option<Pubkey>,
  252. size: u64,
  253. ) -> Result<()> {
  254. let ix = mpl_token_metadata::instructions::SetCollectionSize {
  255. collection_authority: *ctx.accounts.update_authority.key,
  256. collection_authority_record,
  257. collection_metadata: *ctx.accounts.metadata.key,
  258. collection_mint: *ctx.accounts.mint.key,
  259. }
  260. .instruction(
  261. mpl_token_metadata::instructions::SetCollectionSizeInstructionArgs {
  262. set_collection_size_args: mpl_token_metadata::types::SetCollectionSizeArgs { size },
  263. },
  264. );
  265. anchor_lang::solana_program::program::invoke_signed(
  266. &ix,
  267. &ToAccountInfos::to_account_infos(&ctx),
  268. ctx.signer_seeds,
  269. )
  270. .map_err(Into::into)
  271. }
  272. pub fn verify_collection<'info>(
  273. ctx: CpiContext<'_, '_, '_, 'info, VerifyCollection<'info>>,
  274. collection_authority_record: Option<Pubkey>,
  275. ) -> Result<()> {
  276. let ix = mpl_token_metadata::instructions::VerifyCollection {
  277. collection: *ctx.accounts.collection_metadata.key,
  278. collection_authority: *ctx.accounts.collection_authority.key,
  279. collection_authority_record,
  280. collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
  281. collection_mint: *ctx.accounts.collection_mint.key,
  282. metadata: *ctx.accounts.metadata.key,
  283. payer: *ctx.accounts.payer.key,
  284. }
  285. .instruction();
  286. anchor_lang::solana_program::program::invoke_signed(
  287. &ix,
  288. &ToAccountInfos::to_account_infos(&ctx),
  289. ctx.signer_seeds,
  290. )
  291. .map_err(Into::into)
  292. }
  293. pub fn verify_sized_collection_item<'info>(
  294. ctx: CpiContext<'_, '_, '_, 'info, VerifySizedCollectionItem<'info>>,
  295. collection_authority_record: Option<Pubkey>,
  296. ) -> Result<()> {
  297. let ix = mpl_token_metadata::instructions::VerifySizedCollectionItem {
  298. collection: *ctx.accounts.collection_metadata.key,
  299. collection_authority: *ctx.accounts.collection_authority.key,
  300. collection_authority_record,
  301. collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
  302. collection_mint: *ctx.accounts.collection_mint.key,
  303. metadata: *ctx.accounts.metadata.key,
  304. payer: *ctx.accounts.payer.key,
  305. }
  306. .instruction();
  307. anchor_lang::solana_program::program::invoke_signed(
  308. &ix,
  309. &ToAccountInfos::to_account_infos(&ctx),
  310. ctx.signer_seeds,
  311. )
  312. .map_err(Into::into)
  313. }
  314. pub fn set_and_verify_collection<'info>(
  315. ctx: CpiContext<'_, '_, '_, 'info, SetAndVerifyCollection<'info>>,
  316. collection_authority_record: Option<Pubkey>,
  317. ) -> Result<()> {
  318. let ix = mpl_token_metadata::instructions::SetAndVerifyCollection {
  319. collection: *ctx.accounts.collection_metadata.key,
  320. collection_authority: *ctx.accounts.collection_authority.key,
  321. collection_authority_record,
  322. collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
  323. collection_mint: *ctx.accounts.collection_mint.key,
  324. metadata: *ctx.accounts.metadata.key,
  325. payer: *ctx.accounts.payer.key,
  326. update_authority: *ctx.accounts.update_authority.key,
  327. }
  328. .instruction();
  329. anchor_lang::solana_program::program::invoke_signed(
  330. &ix,
  331. &ToAccountInfos::to_account_infos(&ctx),
  332. ctx.signer_seeds,
  333. )
  334. .map_err(Into::into)
  335. }
  336. pub fn set_and_verify_sized_collection_item<'info>(
  337. ctx: CpiContext<'_, '_, '_, 'info, SetAndVerifySizedCollectionItem<'info>>,
  338. collection_authority_record: Option<Pubkey>,
  339. ) -> Result<()> {
  340. let ix = mpl_token_metadata::instructions::SetAndVerifySizedCollectionItem {
  341. collection: *ctx.accounts.collection_metadata.key,
  342. collection_authority: *ctx.accounts.collection_authority.key,
  343. collection_authority_record,
  344. collection_master_edition_account: *ctx.accounts.collection_master_edition.key,
  345. collection_mint: *ctx.accounts.collection_mint.key,
  346. metadata: *ctx.accounts.metadata.key,
  347. payer: *ctx.accounts.payer.key,
  348. update_authority: *ctx.accounts.update_authority.key,
  349. }
  350. .instruction();
  351. anchor_lang::solana_program::program::invoke_signed(
  352. &ix,
  353. &ToAccountInfos::to_account_infos(&ctx),
  354. ctx.signer_seeds,
  355. )
  356. .map_err(Into::into)
  357. }
  358. pub fn freeze_delegated_account<'info>(
  359. ctx: CpiContext<'_, '_, '_, 'info, FreezeDelegatedAccount<'info>>,
  360. ) -> Result<()> {
  361. let ix = mpl_token_metadata::instructions::FreezeDelegatedAccount {
  362. delegate: *ctx.accounts.delegate.key,
  363. edition: *ctx.accounts.edition.key,
  364. mint: *ctx.accounts.mint.key,
  365. token_account: *ctx.accounts.token_account.key,
  366. token_program: *ctx.accounts.token_program.key,
  367. }
  368. .instruction();
  369. anchor_lang::solana_program::program::invoke_signed(
  370. &ix,
  371. &ToAccountInfos::to_account_infos(&ctx),
  372. ctx.signer_seeds,
  373. )
  374. .map_err(Into::into)
  375. }
  376. pub fn thaw_delegated_account<'info>(
  377. ctx: CpiContext<'_, '_, '_, 'info, ThawDelegatedAccount<'info>>,
  378. ) -> Result<()> {
  379. let ix = mpl_token_metadata::instructions::ThawDelegatedAccount {
  380. delegate: *ctx.accounts.delegate.key,
  381. edition: *ctx.accounts.edition.key,
  382. mint: *ctx.accounts.mint.key,
  383. token_account: *ctx.accounts.token_account.key,
  384. token_program: *ctx.accounts.token_program.key,
  385. }
  386. .instruction();
  387. anchor_lang::solana_program::program::invoke_signed(
  388. &ix,
  389. &ToAccountInfos::to_account_infos(&ctx),
  390. ctx.signer_seeds,
  391. )
  392. .map_err(Into::into)
  393. }
  394. pub fn update_primary_sale_happened_via_token<'info>(
  395. ctx: CpiContext<'_, '_, '_, 'info, UpdatePrimarySaleHappenedViaToken<'info>>,
  396. ) -> Result<()> {
  397. let ix = mpl_token_metadata::instructions::UpdatePrimarySaleHappenedViaToken {
  398. metadata: *ctx.accounts.metadata.key,
  399. owner: *ctx.accounts.owner.key,
  400. token: *ctx.accounts.token.key,
  401. }
  402. .instruction();
  403. anchor_lang::solana_program::program::invoke_signed(
  404. &ix,
  405. &ToAccountInfos::to_account_infos(&ctx),
  406. ctx.signer_seeds,
  407. )?;
  408. Ok(())
  409. }
  410. pub fn set_token_standard<'info>(
  411. ctx: CpiContext<'_, '_, '_, 'info, SetTokenStandard<'info>>,
  412. edition_account: Option<Pubkey>,
  413. ) -> Result<()> {
  414. let ix = mpl_token_metadata::instructions::SetTokenStandard {
  415. edition: edition_account,
  416. metadata: *ctx.accounts.metadata_account.key,
  417. mint: *ctx.accounts.mint_account.key,
  418. update_authority: *ctx.accounts.update_authority.key,
  419. }
  420. .instruction();
  421. anchor_lang::solana_program::program::invoke_signed(
  422. &ix,
  423. &ToAccountInfos::to_account_infos(&ctx),
  424. ctx.signer_seeds,
  425. )
  426. .map_err(Into::into)
  427. }
  428. pub fn sign_metadata<'info>(ctx: CpiContext<'_, '_, '_, 'info, SignMetadata<'info>>) -> Result<()> {
  429. let ix = mpl_token_metadata::instructions::SignMetadata {
  430. creator: *ctx.accounts.creator.key,
  431. metadata: *ctx.accounts.metadata.key,
  432. }
  433. .instruction();
  434. anchor_lang::solana_program::program::invoke_signed(
  435. &ix,
  436. &ToAccountInfos::to_account_infos(&ctx),
  437. ctx.signer_seeds,
  438. )?;
  439. Ok(())
  440. }
  441. pub fn remove_creator_verification<'info>(
  442. ctx: CpiContext<'_, '_, '_, 'info, RemoveCreatorVerification<'info>>,
  443. ) -> Result<()> {
  444. let ix = mpl_token_metadata::instructions::RemoveCreatorVerification {
  445. creator: *ctx.accounts.creator.key,
  446. metadata: *ctx.accounts.metadata.key,
  447. }
  448. .instruction();
  449. anchor_lang::solana_program::program::invoke_signed(
  450. &ix,
  451. &ToAccountInfos::to_account_infos(&ctx),
  452. ctx.signer_seeds,
  453. )?;
  454. Ok(())
  455. }
  456. pub fn utilize<'info>(
  457. ctx: CpiContext<'_, '_, '_, 'info, Utilize<'info>>,
  458. use_authority_record: Option<Pubkey>,
  459. burner: Option<Pubkey>,
  460. number_of_uses: u64,
  461. ) -> Result<()> {
  462. let ix = mpl_token_metadata::instructions::Utilize {
  463. ata_program: spl_associated_token_account::ID,
  464. burner,
  465. metadata: *ctx.accounts.metadata.key,
  466. mint: *ctx.accounts.mint.key,
  467. owner: *ctx.accounts.owner.key,
  468. rent: sysvar::rent::ID,
  469. system_program: system_program::ID,
  470. token_account: *ctx.accounts.token_account.key,
  471. token_program: spl_token::ID,
  472. use_authority: *ctx.accounts.use_authority.key,
  473. use_authority_record,
  474. }
  475. .instruction(mpl_token_metadata::instructions::UtilizeInstructionArgs { number_of_uses });
  476. anchor_lang::solana_program::program::invoke_signed(
  477. &ix,
  478. &ToAccountInfos::to_account_infos(&ctx),
  479. ctx.signer_seeds,
  480. )
  481. .map_err(Into::into)
  482. }
  483. pub fn unverify_collection<'info>(
  484. ctx: CpiContext<'_, '_, '_, 'info, UnverifyCollection<'info>>,
  485. collection_authority_record: Option<Pubkey>,
  486. ) -> Result<()> {
  487. let ix = mpl_token_metadata::instructions::UnverifyCollection {
  488. collection: *ctx.accounts.metadata.key,
  489. collection_authority: *ctx.accounts.collection_authority.key,
  490. collection_authority_record,
  491. collection_master_edition_account: *ctx.accounts.collection_master_edition_account.key,
  492. collection_mint: *ctx.accounts.collection_mint.key,
  493. metadata: *ctx.accounts.metadata.key,
  494. }
  495. .instruction();
  496. anchor_lang::solana_program::program::invoke_signed(
  497. &ix,
  498. &ToAccountInfos::to_account_infos(&ctx),
  499. ctx.signer_seeds,
  500. )
  501. .map_err(Into::into)
  502. }
  503. pub fn unverify_sized_collection_item<'info>(
  504. ctx: CpiContext<'_, '_, '_, 'info, UnverifySizedCollectionItem<'info>>,
  505. collection_authority_record: Option<Pubkey>,
  506. ) -> Result<()> {
  507. let ix = mpl_token_metadata::instructions::UnverifySizedCollectionItem {
  508. collection: *ctx.accounts.metadata.key,
  509. collection_authority: *ctx.accounts.collection_authority.key,
  510. collection_authority_record,
  511. collection_master_edition_account: *ctx.accounts.collection_master_edition_account.key,
  512. collection_mint: *ctx.accounts.collection_mint.key,
  513. metadata: *ctx.accounts.metadata.key,
  514. payer: *ctx.accounts.payer.key,
  515. }
  516. .instruction();
  517. anchor_lang::solana_program::program::invoke_signed(
  518. &ix,
  519. &ToAccountInfos::to_account_infos(&ctx),
  520. ctx.signer_seeds,
  521. )
  522. .map_err(Into::into)
  523. }
  524. #[derive(Accounts)]
  525. pub struct ApproveCollectionAuthority<'info> {
  526. pub collection_authority_record: AccountInfo<'info>,
  527. pub new_collection_authority: AccountInfo<'info>,
  528. pub update_authority: AccountInfo<'info>,
  529. pub payer: AccountInfo<'info>,
  530. pub metadata: AccountInfo<'info>,
  531. pub mint: AccountInfo<'info>,
  532. }
  533. #[derive(Accounts)]
  534. pub struct BubblegumSetCollectionSize<'info> {
  535. pub metadata_account: AccountInfo<'info>,
  536. pub update_authority: AccountInfo<'info>,
  537. pub mint: AccountInfo<'info>,
  538. pub bubblegum_signer: AccountInfo<'info>,
  539. }
  540. #[derive(Accounts)]
  541. pub struct BurnEditionNft<'info> {
  542. pub metadata: AccountInfo<'info>,
  543. pub owner: AccountInfo<'info>,
  544. pub print_edition_mint: AccountInfo<'info>,
  545. pub master_edition_mint: AccountInfo<'info>,
  546. pub print_edition_token: AccountInfo<'info>,
  547. pub master_edition_token: AccountInfo<'info>,
  548. pub master_edition: AccountInfo<'info>,
  549. pub print_edition: AccountInfo<'info>,
  550. pub edition_marker: AccountInfo<'info>,
  551. pub spl_token: AccountInfo<'info>,
  552. }
  553. #[derive(Accounts)]
  554. pub struct BurnNft<'info> {
  555. pub metadata: AccountInfo<'info>,
  556. pub owner: AccountInfo<'info>,
  557. pub mint: AccountInfo<'info>,
  558. pub token: AccountInfo<'info>,
  559. pub edition: AccountInfo<'info>,
  560. pub spl_token: AccountInfo<'info>,
  561. }
  562. #[derive(Accounts)]
  563. pub struct CreateMetadataAccountsV3<'info> {
  564. pub metadata: AccountInfo<'info>,
  565. pub mint: AccountInfo<'info>,
  566. pub mint_authority: AccountInfo<'info>,
  567. pub payer: AccountInfo<'info>,
  568. pub update_authority: AccountInfo<'info>,
  569. pub system_program: AccountInfo<'info>,
  570. pub rent: AccountInfo<'info>,
  571. }
  572. #[derive(Accounts)]
  573. pub struct UpdateMetadataAccountsV2<'info> {
  574. pub metadata: AccountInfo<'info>,
  575. pub update_authority: AccountInfo<'info>,
  576. }
  577. #[derive(Accounts)]
  578. pub struct CreateMasterEditionV3<'info> {
  579. pub edition: AccountInfo<'info>,
  580. pub mint: AccountInfo<'info>,
  581. pub update_authority: AccountInfo<'info>,
  582. pub mint_authority: AccountInfo<'info>,
  583. pub payer: AccountInfo<'info>,
  584. pub metadata: AccountInfo<'info>,
  585. pub token_program: AccountInfo<'info>,
  586. pub system_program: AccountInfo<'info>,
  587. pub rent: AccountInfo<'info>,
  588. }
  589. #[derive(Accounts)]
  590. pub struct MintNewEditionFromMasterEditionViaToken<'info> {
  591. pub new_metadata: AccountInfo<'info>,
  592. pub new_edition: AccountInfo<'info>,
  593. pub master_edition: AccountInfo<'info>,
  594. pub new_mint: AccountInfo<'info>,
  595. pub edition_mark_pda: AccountInfo<'info>,
  596. pub new_mint_authority: AccountInfo<'info>,
  597. pub payer: AccountInfo<'info>,
  598. pub token_account_owner: AccountInfo<'info>,
  599. pub token_account: AccountInfo<'info>,
  600. pub new_metadata_update_authority: AccountInfo<'info>,
  601. pub metadata: AccountInfo<'info>,
  602. pub token_program: AccountInfo<'info>,
  603. pub system_program: AccountInfo<'info>,
  604. pub rent: AccountInfo<'info>,
  605. //
  606. // Not actually used by the program but still needed because it's needed
  607. // for the pda calculation in the helper. :/
  608. //
  609. // The better thing to do would be to remove this and have the instruction
  610. // helper pass in the `edition_mark_pda` directly.
  611. //
  612. pub metadata_mint: AccountInfo<'info>,
  613. }
  614. #[derive(Accounts)]
  615. pub struct RevokeCollectionAuthority<'info> {
  616. pub collection_authority_record: AccountInfo<'info>,
  617. pub delegate_authority: AccountInfo<'info>,
  618. pub revoke_authority: AccountInfo<'info>,
  619. pub metadata: AccountInfo<'info>,
  620. pub mint: AccountInfo<'info>,
  621. }
  622. #[derive(Accounts)]
  623. pub struct SetCollectionSize<'info> {
  624. pub metadata: AccountInfo<'info>,
  625. pub mint: AccountInfo<'info>,
  626. pub update_authority: AccountInfo<'info>,
  627. pub system_program: AccountInfo<'info>,
  628. }
  629. #[derive(Accounts)]
  630. pub struct SetTokenStandard<'info> {
  631. pub metadata_account: AccountInfo<'info>,
  632. pub update_authority: AccountInfo<'info>,
  633. pub mint_account: AccountInfo<'info>,
  634. }
  635. #[derive(Accounts)]
  636. pub struct VerifyCollection<'info> {
  637. pub payer: AccountInfo<'info>,
  638. pub metadata: AccountInfo<'info>,
  639. pub collection_authority: AccountInfo<'info>,
  640. pub collection_mint: AccountInfo<'info>,
  641. pub collection_metadata: AccountInfo<'info>,
  642. pub collection_master_edition: AccountInfo<'info>,
  643. }
  644. #[derive(Accounts)]
  645. pub struct VerifySizedCollectionItem<'info> {
  646. pub payer: AccountInfo<'info>,
  647. pub metadata: AccountInfo<'info>,
  648. pub collection_authority: AccountInfo<'info>,
  649. pub collection_mint: AccountInfo<'info>,
  650. pub collection_metadata: AccountInfo<'info>,
  651. pub collection_master_edition: AccountInfo<'info>,
  652. }
  653. #[derive(Accounts)]
  654. pub struct SetAndVerifyCollection<'info> {
  655. pub metadata: AccountInfo<'info>,
  656. pub collection_authority: AccountInfo<'info>,
  657. pub payer: AccountInfo<'info>,
  658. pub update_authority: AccountInfo<'info>,
  659. pub collection_mint: AccountInfo<'info>,
  660. pub collection_metadata: AccountInfo<'info>,
  661. pub collection_master_edition: AccountInfo<'info>,
  662. }
  663. #[derive(Accounts)]
  664. pub struct SetAndVerifySizedCollectionItem<'info> {
  665. pub metadata: AccountInfo<'info>,
  666. pub collection_authority: AccountInfo<'info>,
  667. pub payer: AccountInfo<'info>,
  668. pub update_authority: AccountInfo<'info>,
  669. pub collection_mint: AccountInfo<'info>,
  670. pub collection_metadata: AccountInfo<'info>,
  671. pub collection_master_edition: AccountInfo<'info>,
  672. }
  673. #[derive(Accounts)]
  674. pub struct FreezeDelegatedAccount<'info> {
  675. pub metadata: AccountInfo<'info>,
  676. pub delegate: AccountInfo<'info>,
  677. pub token_account: AccountInfo<'info>,
  678. pub edition: AccountInfo<'info>,
  679. pub mint: AccountInfo<'info>,
  680. pub token_program: AccountInfo<'info>,
  681. }
  682. #[derive(Accounts)]
  683. pub struct ThawDelegatedAccount<'info> {
  684. pub metadata: AccountInfo<'info>,
  685. pub delegate: AccountInfo<'info>,
  686. pub token_account: AccountInfo<'info>,
  687. pub edition: AccountInfo<'info>,
  688. pub mint: AccountInfo<'info>,
  689. pub token_program: AccountInfo<'info>,
  690. }
  691. #[derive(Accounts)]
  692. pub struct UpdatePrimarySaleHappenedViaToken<'info> {
  693. pub metadata: AccountInfo<'info>,
  694. pub owner: AccountInfo<'info>,
  695. pub token: AccountInfo<'info>,
  696. }
  697. #[derive(Accounts)]
  698. pub struct SignMetadata<'info> {
  699. pub creator: AccountInfo<'info>,
  700. pub metadata: AccountInfo<'info>,
  701. }
  702. #[derive(Accounts)]
  703. pub struct RemoveCreatorVerification<'info> {
  704. pub creator: AccountInfo<'info>,
  705. pub metadata: AccountInfo<'info>,
  706. }
  707. #[derive(Accounts)]
  708. pub struct Utilize<'info> {
  709. pub metadata: AccountInfo<'info>,
  710. pub token_account: AccountInfo<'info>,
  711. pub mint: AccountInfo<'info>,
  712. pub use_authority: AccountInfo<'info>,
  713. pub owner: AccountInfo<'info>,
  714. }
  715. #[derive(Accounts)]
  716. pub struct UnverifyCollection<'info> {
  717. pub metadata: AccountInfo<'info>,
  718. pub collection_authority: AccountInfo<'info>,
  719. pub collection_mint: AccountInfo<'info>,
  720. pub collection: AccountInfo<'info>,
  721. pub collection_master_edition_account: AccountInfo<'info>,
  722. }
  723. #[derive(Accounts)]
  724. pub struct UnverifySizedCollectionItem<'info> {
  725. pub metadata: AccountInfo<'info>,
  726. pub collection_authority: AccountInfo<'info>,
  727. pub payer: AccountInfo<'info>,
  728. pub collection_mint: AccountInfo<'info>,
  729. pub collection: AccountInfo<'info>,
  730. pub collection_master_edition_account: AccountInfo<'info>,
  731. }
  732. #[derive(Clone, Debug, PartialEq)]
  733. pub struct MetadataAccount(mpl_token_metadata::accounts::Metadata);
  734. impl anchor_lang::AccountDeserialize for MetadataAccount {
  735. fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
  736. let md = Self::try_deserialize_unchecked(buf)?;
  737. if md.key != mpl_token_metadata::types::Key::MetadataV1 {
  738. return Err(ErrorCode::AccountNotInitialized.into());
  739. }
  740. Ok(md)
  741. }
  742. fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
  743. let md = mpl_token_metadata::accounts::Metadata::safe_deserialize(buf)?;
  744. Ok(Self(md))
  745. }
  746. }
  747. impl anchor_lang::AccountSerialize for MetadataAccount {}
  748. impl anchor_lang::Owner for MetadataAccount {
  749. fn owner() -> Pubkey {
  750. ID
  751. }
  752. }
  753. impl Deref for MetadataAccount {
  754. type Target = mpl_token_metadata::accounts::Metadata;
  755. fn deref(&self) -> &Self::Target {
  756. &self.0
  757. }
  758. }
  759. #[derive(Clone, Debug, PartialEq)]
  760. pub struct MasterEditionAccount(mpl_token_metadata::accounts::MasterEdition);
  761. impl anchor_lang::AccountDeserialize for MasterEditionAccount {
  762. fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
  763. let me = Self::try_deserialize_unchecked(buf)?;
  764. if me.key != mpl_token_metadata::types::Key::MasterEditionV2 {
  765. return Err(ErrorCode::AccountNotInitialized.into());
  766. }
  767. Ok(me)
  768. }
  769. fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
  770. let result = mpl_token_metadata::accounts::MasterEdition::safe_deserialize(buf)?;
  771. Ok(Self(result))
  772. }
  773. }
  774. impl Deref for MasterEditionAccount {
  775. type Target = mpl_token_metadata::accounts::MasterEdition;
  776. fn deref(&self) -> &Self::Target {
  777. &self.0
  778. }
  779. }
  780. impl anchor_lang::AccountSerialize for MasterEditionAccount {}
  781. impl anchor_lang::Owner for MasterEditionAccount {
  782. fn owner() -> Pubkey {
  783. ID
  784. }
  785. }
  786. #[derive(Clone, Debug, PartialEq)]
  787. pub struct TokenRecordAccount(mpl_token_metadata::accounts::TokenRecord);
  788. impl TokenRecordAccount {
  789. pub const LEN: usize = mpl_token_metadata::accounts::TokenRecord::LEN;
  790. }
  791. impl anchor_lang::AccountDeserialize for TokenRecordAccount {
  792. fn try_deserialize(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
  793. let tr = Self::try_deserialize_unchecked(buf)?;
  794. if tr.key != mpl_token_metadata::types::Key::TokenRecord {
  795. return Err(ErrorCode::AccountNotInitialized.into());
  796. }
  797. Ok(tr)
  798. }
  799. fn try_deserialize_unchecked(buf: &mut &[u8]) -> anchor_lang::Result<Self> {
  800. let tr = mpl_token_metadata::accounts::TokenRecord::safe_deserialize(buf)?;
  801. Ok(Self(tr))
  802. }
  803. }
  804. impl anchor_lang::AccountSerialize for TokenRecordAccount {}
  805. impl anchor_lang::Owner for TokenRecordAccount {
  806. fn owner() -> Pubkey {
  807. ID
  808. }
  809. }
  810. impl Deref for TokenRecordAccount {
  811. type Target = mpl_token_metadata::accounts::TokenRecord;
  812. fn deref(&self) -> &Self::Target {
  813. &self.0
  814. }
  815. }
  816. #[derive(Clone)]
  817. pub struct Metadata;
  818. impl anchor_lang::Id for Metadata {
  819. fn id() -> Pubkey {
  820. ID
  821. }
  822. }