From e5026d85f193d78050c1e85c92c5243b43b93680 Mon Sep 17 00:00:00 2001 From: Samuel Vanderwaal Date: Mon, 31 Jan 2022 23:42:52 -0900 Subject: [PATCH] feat(set): add set immutable commands; update to mpl-token-metadata v1.1.0 --- Cargo.lock | 32 +-------------------- Cargo.toml | 2 +- RELEASE_NOTES.md | 5 ++++ src/burn.rs | 2 +- src/decode.rs | 4 ++- src/derive.rs | 2 +- src/mint.rs | 2 +- src/opt.rs | 20 +++++++++++++ src/parse.rs | 2 +- src/process_subcommands.rs | 8 ++++++ src/sign.rs | 4 +-- src/snapshot.rs | 4 +-- src/update_metadata.rs | 59 ++++++++++++++++++++++++++++++++++++-- 13 files changed, 101 insertions(+), 45 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d9703855..625dea2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1700,8 +1700,8 @@ dependencies = [ "indicatif", "lazy_static", "log", - "metaplex-token-metadata", "mpl-candy-machine", + "mpl-token-metadata", "num_cpus", "ratelimit", "rayon", @@ -1720,36 +1720,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "metaplex-token-metadata" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abcc939f0afdc6db054b9998a1292d0a016244b382462e61cfc7c570624982cb" -dependencies = [ - "arrayref", - "borsh", - "metaplex-token-vault", - "num-derive", - "num-traits", - "solana-program", - "spl-token", - "thiserror", -] - -[[package]] -name = "metaplex-token-vault" -version = "0.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5211991ba3273df89cd5e0f6f558bc8d7453c87c0546f915b4a319e1541df33" -dependencies = [ - "borsh", - "num-derive", - "num-traits", - "solana-program", - "spl-token", - "thiserror", -] - [[package]] name = "mime" version = "0.3.16" diff --git a/Cargo.toml b/Cargo.toml index 91944900..0b59dbad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ glob = "0.3.0" indicatif = { version = "0.16.2", features = ["rayon"] } lazy_static = "1.4.0" log = "0.4.14" -metaplex-token-metadata = "0.0.1" +mpl-token-metadata = "1.1.0" mpl-candy-machine = { version = "2.0.1", features = ["no-entrypoint"] } num_cpus = "1.13.0" ratelimit = "0.4.4" diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index f0f05fa8..f780cff8 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,5 +1,10 @@ v0.4.0 * Change decode default format to data struct to match input required from `update-metadata` command +* Add `set immutable` and `set immutable` all commands +* Updated to use `mpl-token-metadata v1.1.0` + +TODO: +* Set primary sale and set immutable, fix progress bar by not writing to log within par_iter loop v0.3.6 * Add withdraw command for candy machine v2 diff --git a/src/burn.rs b/src/burn.rs index 6293f671..418c2e09 100644 --- a/src/burn.rs +++ b/src/burn.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use metaplex_token_metadata::{ +use mpl_token_metadata::{ id, instruction::update_metadata_accounts, state::{Data, Metadata}, diff --git a/src/decode.rs b/src/decode.rs index 8d47f3bf..9ec1f409 100644 --- a/src/decode.rs +++ b/src/decode.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Result as AnyResult}; use indicatif::ParallelProgressIterator; use log::{debug, error, info}; -use metaplex_token_metadata::state::{Key, Metadata}; +use mpl_token_metadata::state::{Key, Metadata}; use rayon::prelude::*; use retry::{delay::Exponential, retry}; use serde::Serialize; @@ -231,5 +231,7 @@ fn parse_key(key: Key) -> String { Key::ReservationListV2 => String::from("ReservationListV2"), Key::MasterEditionV2 => String::from("MasterEditionV2"), Key::EditionMarker => String::from("EditionMarker"), + Key::UseAuthorityRecord => String::from("UseAuthorityRecord"), + Key::CollectionAuthorityRecord => String::from("CollectionAuthorityRecord"), } } diff --git a/src/derive.rs b/src/derive.rs index 025373e0..d04cef04 100644 --- a/src/derive.rs +++ b/src/derive.rs @@ -1,4 +1,4 @@ -use metaplex_token_metadata::id; +use mpl_token_metadata::id; use solana_sdk::pubkey::Pubkey; use std::{convert::AsRef, str::FromStr}; diff --git a/src/mint.rs b/src/mint.rs index 7a9006b3..eeb3a6cc 100644 --- a/src/mint.rs +++ b/src/mint.rs @@ -1,7 +1,7 @@ use anyhow::{anyhow, Result}; use glob::glob; use log::{error, info}; -use metaplex_token_metadata::instruction::{ +use mpl_token_metadata::instruction::{ create_master_edition, create_metadata_accounts, update_metadata_accounts, }; use rayon::prelude::*; diff --git a/src/opt.rs b/src/opt.rs index 35b668ea..623cf0a9 100644 --- a/src/opt.rs +++ b/src/opt.rs @@ -234,6 +234,26 @@ pub enum SetSubcommands { #[structopt(short = "u", long)] new_update_authority: String, }, + /// Set is-mutable to false, preventing any future updates to the NFT + #[structopt(name = "immutable")] + Immutable { + /// Path to the creator's keypair file + #[structopt(short, long)] + keypair: String, + + /// Mint account of corresponding metadata to update + #[structopt(short, long)] + mint_account: String, + }, + ImmutableAll { + /// Path to the creator's keypair file + #[structopt(short, long)] + keypair: String, + + /// Path to JSON mint accounts file + #[structopt(short, long)] + mint_accounts_file: String, + }, } #[derive(Debug, StructOpt)] diff --git a/src/parse.rs b/src/parse.rs index 9666df43..11084b32 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,5 +1,5 @@ use anyhow::{anyhow, Context, Result}; -use metaplex_token_metadata::state::{Creator, Data}; +use mpl_token_metadata::state::{Creator, Data}; use serde::{Deserialize, Serialize}; use serde_json::Value; use solana_sdk::pubkey::Pubkey; diff --git a/src/process_subcommands.rs b/src/process_subcommands.rs index 4d13eda2..06ede401 100644 --- a/src/process_subcommands.rs +++ b/src/process_subcommands.rs @@ -95,6 +95,14 @@ pub fn process_set(client: &RpcClient, commands: SetSubcommands) -> Result<()> { &mint_accounts_file, &new_update_authority, ), + SetSubcommands::Immutable { + keypair, + mint_account, + } => set_immutable(&client, &keypair, &mint_account), + SetSubcommands::ImmutableAll { + keypair, + mint_accounts_file, + } => set_immutable_all(&client, &keypair, &mint_accounts_file), } } diff --git a/src/sign.rs b/src/sign.rs index 49ef8b97..27b65851 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -1,9 +1,7 @@ use anyhow::{anyhow, Result}; use indicatif::ParallelProgressIterator; use log::{error, info}; -use metaplex_token_metadata::{ - instruction::sign_metadata, state::Metadata, ID as METAPLEX_PROGRAM_ID, -}; +use mpl_token_metadata::{instruction::sign_metadata, state::Metadata, ID as METAPLEX_PROGRAM_ID}; use rayon::prelude::*; use retry::{delay::Exponential, retry}; use solana_client::rpc_client::RpcClient; diff --git a/src/snapshot.rs b/src/snapshot.rs index 505c5efd..ade3cef3 100644 --- a/src/snapshot.rs +++ b/src/snapshot.rs @@ -1,8 +1,8 @@ use anyhow::{anyhow, Result}; use indicatif::ParallelProgressIterator; use log::{error, info}; -use metaplex_token_metadata::state::Metadata; -use metaplex_token_metadata::ID as TOKEN_METADATA_PROGRAM_ID; +use mpl_token_metadata::state::Metadata; +use mpl_token_metadata::ID as TOKEN_METADATA_PROGRAM_ID; use rayon::prelude::*; use retry::{delay::Exponential, retry}; use serde::Serialize; diff --git a/src/update_metadata.rs b/src/update_metadata.rs index 89d6baf1..ba73848d 100644 --- a/src/update_metadata.rs +++ b/src/update_metadata.rs @@ -2,7 +2,10 @@ use anyhow::{anyhow, Result}; use glob::glob; use indicatif::ParallelProgressIterator; use log::{error, info}; -use metaplex_token_metadata::{instruction::update_metadata_accounts, state::Data}; +use mpl_token_metadata::{ + instruction::{update_metadata_accounts, update_metadata_accounts_v2}, + state::Data, +}; use rayon::prelude::*; use retry::{delay::Exponential, retry}; use solana_client::rpc_client::RpcClient; @@ -315,8 +318,6 @@ pub fn set_update_authority_all( info!("Setting update_authority..."); items.par_iter().progress().for_each(|item| { - info!("Updating metadata for mint account: {}", item); - // If someone uses a json list that contains a mint account that has already // been updated this will throw an error. We print that error and continue let _ = match set_update_authority(client, keypair, &item, &new_update_authority) { @@ -329,3 +330,55 @@ pub fn set_update_authority_all( Ok(()) } + +pub fn set_immutable(client: &RpcClient, keypair: &String, account: &String) -> Result<()> { + let keypair = parse_keypair(keypair)?; + let program_id = Pubkey::from_str(METAPLEX_PROGRAM_ID)?; + let mint_account = Pubkey::from_str(account)?; + + let update_authority = keypair.pubkey(); + + let metadata_account = get_metadata_pda(mint_account); + + let ix = update_metadata_accounts_v2( + program_id, + metadata_account, + update_authority, + None, + None, + None, + Some(false), + ); + let recent_blockhash = client.get_latest_blockhash()?; + let tx = Transaction::new_signed_with_payer( + &[ix], + Some(&update_authority), + &[&keypair], + recent_blockhash, + ); + + let sig = client.send_and_confirm_transaction(&tx)?; + info!("Tx sig: {:?}", sig); + println!("Tx sig: {:?}", sig); + + Ok(()) +} + +pub fn set_immutable_all(client: &RpcClient, keypair: &String, json_file: &String) -> Result<()> { + let file = File::open(json_file)?; + let items: Vec = serde_json::from_reader(file)?; + + info!("Setting immutable..."); + items.par_iter().progress().for_each(|item| { + // If someone uses a json list that contains a mint account that has already + // been updated this will throw an error. We print that error and continue + let _ = match set_immutable(client, keypair, &item) { + Ok(_) => {} + Err(error) => { + error!("Error occurred! {}", error) + } + }; + }); + + Ok(()) +}