Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(token-metadata): add burn_print_edition handler #684

Merged
merged 27 commits into from
Sep 19, 2022
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
681652d
feat(token-metadata): add burn_print_edition handler
samuelvanderwaal Aug 19, 2022
8cb4b4f
Merge branch 'master' into feat/burn-print-editions
samuelvanderwaal Aug 19, 2022
fed8698
fix(burn-print-edition): clippy lints
samuelvanderwaal Aug 23, 2022
e949d4e
fix: clippy lints
samuelvanderwaal Aug 23, 2022
a20d4fc
tests(token-metadata): add more tests
samuelvanderwaal Aug 23, 2022
5f3d0cb
chore(token-metadata): generate JS code for burn_edition_nft
samuelvanderwaal Aug 23, 2022
8d62056
Merge branch 'master' into feat/burn-print-editions
samuelvanderwaal Aug 24, 2022
ea15701
test(burn_edition_nft): only holder of print edition can burn
samuelvanderwaal Aug 24, 2022
836937a
test(token-metadata/burn_edition_nft): reprint burned nft
samuelvanderwaal Aug 25, 2022
e0fb85e
chore(token-metadata): merge master into branch
samuelvanderwaal Aug 25, 2022
b9a4b0c
test(token-metadata) refactor burn_edition_nft tests a little
samuelvanderwaal Aug 25, 2022
455c745
test(token-metdata): make mask check more complex
samuelvanderwaal Aug 25, 2022
2ec0b82
fix: clippy lints
samuelvanderwaal Aug 25, 2022
ded9c23
refactor: fix supply account; decrement max_supply
samuelvanderwaal Aug 31, 2022
3ffe8a8
chore: merge master into branch
samuelvanderwaal Aug 31, 2022
662c5e7
Merge branch 'master' into feat/burn-print-editions
samuelvanderwaal Sep 8, 2022
4f19f68
finish spec implementation; update tests
samuelvanderwaal Sep 14, 2022
da20c43
Merge branch 'master' into feat/burn-print-editions
samuelvanderwaal Sep 14, 2022
72257b1
refactor: update tests for new supply accounting; remove unused fn
samuelvanderwaal Sep 14, 2022
ce68d7e
chore: generate JS lib for token metadata
samuelvanderwaal Sep 14, 2022
a836cbc
chore: clean up tests
samuelvanderwaal Sep 14, 2022
c657d1c
fix: decrement max supply correctly
samuelvanderwaal Sep 14, 2022
cdfebb8
add missing check; regnerate JS api
samuelvanderwaal Sep 16, 2022
6307d9a
refactor: address review comments
samuelvanderwaal Sep 19, 2022
b92e489
add tests checking invalid master & print derivations
samuelvanderwaal Sep 19, 2022
6aefd85
tests: add a few more tests
samuelvanderwaal Sep 19, 2022
3326dd1
chore(token-metadata/js): generate JS lib
samuelvanderwaal Sep 19, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions token-metadata/js/idl/mpl_token_metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2044,6 +2044,70 @@
"type": "u8",
"value": 36
}
},
{
"name": "BurnEditionNft",
"accounts": [
{
"name": "metadata",
"isMut": true,
"isSigner": false,
"desc": "Metadata (pda of ['metadata', program id, mint id])"
},
{
"name": "owner",
"isMut": true,
"isSigner": true,
"desc": "NFT owner"
},
{
"name": "mint",
"isMut": true,
"isSigner": false,
"desc": "Mint of the print edition NFT"
},
{
"name": "originalMint",
"isMut": true,
"isSigner": false,
"desc": "Mint of the original/master NFT"
},
{
"name": "tokenAccount",
"isMut": true,
"isSigner": false,
"desc": "Token account the print edition NFT is in"
},
{
"name": "masterEditionAccount",
"isMut": true,
"isSigner": false,
"desc": "MasterEdition2 of the original NFT"
},
{
"name": "editionAccount",
"isMut": true,
"isSigner": false,
"desc": "Print Edition account of the NFT"
},
{
"name": "editionMarkerAccount",
"isMut": true,
"isSigner": false,
"desc": "Edition Marker PDA of the NFT"
},
{
"name": "splTokenProgram",
"isMut": false,
"isSigner": false,
"desc": "SPL Token Program"
}
],
"args": [],
"discriminant": {
"type": "u8",
"value": 36
}
}
],
"accounts": [
Expand Down Expand Up @@ -3419,6 +3483,16 @@
"code": 115,
"name": "AlreadyUnverified",
"msg": "Item is already unverified."
},
{
"code": 116,
"name": "NotAPrintEdition",
"msg": "This edition is not a Print Edition"
},
{
"code": 117,
"name": "InvalidEditionMarker",
"msg": "Invalid Edition Marker"
}
],
"metadata": {
Expand Down
40 changes: 40 additions & 0 deletions token-metadata/js/src/generated/errors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2502,6 +2502,46 @@ export class AlreadyUnverifiedError extends Error {
createErrorFromCodeLookup.set(0x73, () => new AlreadyUnverifiedError());
createErrorFromNameLookup.set('AlreadyUnverified', () => new AlreadyUnverifiedError());

/**
* NotAPrintEdition: 'This edition is not a Print Edition'
*
* @category Errors
* @category generated
*/
export class NotAPrintEditionError extends Error {
readonly code: number = 0x74;
readonly name: string = 'NotAPrintEdition';
constructor() {
super('This edition is not a Print Edition');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, NotAPrintEditionError);
}
}
}

createErrorFromCodeLookup.set(0x74, () => new NotAPrintEditionError());
createErrorFromNameLookup.set('NotAPrintEdition', () => new NotAPrintEditionError());

/**
* InvalidEditionMarker: 'Invalid Edition Marker'
*
* @category Errors
* @category generated
*/
export class InvalidEditionMarkerError extends Error {
readonly code: number = 0x75;
readonly name: string = 'InvalidEditionMarker';
constructor() {
super('Invalid Edition Marker');
if (typeof Error.captureStackTrace === 'function') {
Error.captureStackTrace(this, InvalidEditionMarkerError);
}
}
}

createErrorFromCodeLookup.set(0x75, () => new InvalidEditionMarkerError());
createErrorFromNameLookup.set('InvalidEditionMarker', () => new InvalidEditionMarkerError());

/**
* Attempts to resolve a custom program error from the provided error code.
* @category Errors
Expand Down
119 changes: 119 additions & 0 deletions token-metadata/js/src/generated/instructions/BurnEditionNft.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
* This code was GENERATED using the solita package.
* Please DO NOT EDIT THIS FILE, instead rerun solita to update it or write a wrapper to add functionality.
*
* See: https://github.com/metaplex-foundation/solita
*/

import * as beet from '@metaplex-foundation/beet';
import * as web3 from '@solana/web3.js';

/**
* @category Instructions
* @category BurnEditionNft
* @category generated
*/
export const BurnEditionNftStruct = new beet.BeetArgsStruct<{ instructionDiscriminator: number }>(
[['instructionDiscriminator', beet.u8]],
'BurnEditionNftInstructionArgs',
);
/**
* Accounts required by the _BurnEditionNft_ instruction
*
* @property [_writable_] metadata Metadata (pda of ['metadata', program id, mint id])
* @property [_writable_, **signer**] owner NFT owner
* @property [_writable_] mint Mint of the print edition NFT
* @property [_writable_] originalMint Mint of the original/master NFT
* @property [_writable_] tokenAccount Token account the print edition NFT is in
* @property [_writable_] masterEditionAccount MasterEdition2 of the original NFT
* @property [_writable_] editionAccount Print Edition account of the NFT
* @property [_writable_] editionMarkerAccount Edition Marker PDA of the NFT
* @property [] splTokenProgram SPL Token Program
* @category Instructions
* @category BurnEditionNft
* @category generated
*/
export type BurnEditionNftInstructionAccounts = {
metadata: web3.PublicKey;
owner: web3.PublicKey;
mint: web3.PublicKey;
originalMint: web3.PublicKey;
tokenAccount: web3.PublicKey;
masterEditionAccount: web3.PublicKey;
editionAccount: web3.PublicKey;
editionMarkerAccount: web3.PublicKey;
splTokenProgram: web3.PublicKey;
};

export const burnEditionNftInstructionDiscriminator = 36;

/**
* Creates a _BurnEditionNft_ instruction.
*
* @param accounts that will be accessed while the instruction is processed
* @category Instructions
* @category BurnEditionNft
* @category generated
*/
export function createBurnEditionNftInstruction(
accounts: BurnEditionNftInstructionAccounts,
programId = new web3.PublicKey('metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s'),
) {
const [data] = BurnEditionNftStruct.serialize({
instructionDiscriminator: burnEditionNftInstructionDiscriminator,
});
const keys: web3.AccountMeta[] = [
{
pubkey: accounts.metadata,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.owner,
isWritable: true,
isSigner: true,
},
{
pubkey: accounts.mint,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.originalMint,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.tokenAccount,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.masterEditionAccount,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.editionAccount,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.editionMarkerAccount,
isWritable: true,
isSigner: false,
},
{
pubkey: accounts.splTokenProgram,
isWritable: false,
isSigner: false,
},
];

const ix = new web3.TransactionInstruction({
programId,
keys,
data,
});
return ix;
}
1 change: 1 addition & 0 deletions token-metadata/js/src/generated/instructions/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from './ApproveCollectionAuthority';
export * from './ApproveUseAuthority';
export * from './BubblegumSetCollectionSize';
export * from './BurnEditionNft';
export * from './BurnNft';
export * from './ConvertMasterEditionV1ToV2';
export * from './CreateMasterEdition';
Expand Down
8 changes: 8 additions & 0 deletions token-metadata/program/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,14 @@ pub enum MetadataError {
/// 115 - Item is already unverified.
#[error("Item is already unverified.")]
AlreadyUnverified,

/// 116 - Not a Print Edition
#[error("This edition is not a Print Edition")]
NotAPrintEdition,

/// 117 - Invalid Edition Marker
#[error("Invalid Edition Marker")]
InvalidEditionMarker,
}

impl PrintProgramError for MetadataError {
Expand Down
52 changes: 52 additions & 0 deletions token-metadata/program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,18 @@ pub enum MetadataInstruction {
#[account(3, signer, name="bubblegum_signer", desc="Signing PDA of Bubblegum program")]
#[account(4, optional, name="collection_authority_record", desc="Collection Authority Record PDA")]
BubblegumSetCollectionSize(SetCollectionSizeArgs),

/// Completely burn a print edition NFT.
#[account(0, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")]
#[account(1, signer, writable, name="owner", desc="NFT owner")]
#[account(2, writable, name="mint", desc="Mint of the print edition NFT")]
#[account(3, writable, name="original_mint", desc="Mint of the original/master NFT")]
#[account(4, writable, name="token_account", desc="Token account the print edition NFT is in")]
#[account(5, writable, name="master_edition_account", desc="MasterEdition2 of the original NFT")]
#[account(6, writable, name="edition_account", desc="Print Edition account of the NFT")]
#[account(7, writable, name="edition_marker_account", desc="Edition Marker PDA of the NFT")]
#[account(8, name="spl token program", desc="SPL Token Program")]
BurnEditionNft,
}

/// Creates an CreateMetadataAccounts instruction
Expand Down Expand Up @@ -1430,6 +1442,46 @@ pub fn burn_nft(
}
}

// #[account(0, writable, name="metadata", desc="Metadata (pda of ['metadata', program id, mint id])")]
austbot marked this conversation as resolved.
Show resolved Hide resolved
// #[account(1, signer, writable, name="owner", desc="NFT owner")]
// #[account(2, writable, name="mint", desc="Mint of the print edition NFT")]
// #[account(3, writable, name="original_mint", desc="Mint of the original/master NFT")]
// #[account(4, writable, name="token_account", desc="Token account the print edition NFT is in")]
// #[account(5, writable, name="master_edition_account", desc="MasterEdition2 of the original NFT")]
// #[account(6, writable, name="edition_account", desc="Print Edition account of the NFT")]
// #[account(7, writable, name="edition_marker_account", desc="Edition Marker PDA of the NFT")]
// #[account(8, name="spl token program", desc="SPL Token Program")]
pub fn burn_edition_nft(
program_id: Pubkey,
metadata: Pubkey,
owner: Pubkey,
mint: Pubkey,
original_mint: Pubkey,
token: Pubkey,
master_edition: Pubkey,
edition: Pubkey,
edition_marker: Pubkey,
spl_token: Pubkey,
) -> Instruction {
let accounts = vec![
AccountMeta::new(metadata, false),
AccountMeta::new(owner, true),
AccountMeta::new(mint, false),
AccountMeta::new(original_mint, false),
AccountMeta::new(token, false),
AccountMeta::new(master_edition, false),
AccountMeta::new(edition, false),
AccountMeta::new(edition_marker, false),
AccountMeta::new_readonly(spl_token, false),
];

Instruction {
program_id,
accounts,
data: MetadataInstruction::BurnEditionNft.try_to_vec().unwrap(),
}
}

/// # Verify Collection V2 -- Supports v1.3 Collection Details
///
/// If a MetadataAccount Has a Collection allow the UpdateAuthority of the Collection to Verify the NFT Belongs in the Collection
Expand Down
Loading