From d7fe06b17441f45cb60930e67d251300a5148e3a Mon Sep 17 00:00:00 2001 From: Blockiosaurus Date: Mon, 12 Aug 2024 21:01:41 -0400 Subject: [PATCH] WIP Sugar v3, Core --- .autodoc/docs/markdown/src/common.md | 10 +- .../docs/markdown/src/config/guard_data.md | 22 +- .autodoc/docs/markdown/src/config/summary.md | 2 +- .autodoc/docs/markdown/src/guard/remove.md | 10 +- .autodoc/docs/markdown/src/guard/withdraw.md | 10 +- Cargo.lock | 1536 ++++++++++++----- Cargo.toml | 45 +- src/airdrop/process.rs | 6 +- src/bundlr/process.rs | 2 +- src/cache.rs | 2 +- src/candy_machine.rs | 20 +- src/cli/mod.rs | 62 +- src/collections/set.rs | 83 +- src/common.rs | 4 +- src/config/data.rs | 105 +- src/config/guard_data.rs | 179 +- src/constants.rs | 5 - src/create_config/process.rs | 162 +- src/deploy/collection.rs | 114 +- src/deploy/config_lines.rs | 7 +- src/deploy/initialize.rs | 83 +- src/deploy/process.rs | 17 +- src/freeze/initialize.rs | 4 +- src/freeze/mod.rs | 11 +- src/freeze/thaw.rs | 338 +--- src/freeze/unlock_funds.rs | 4 +- src/guard/add.rs | 8 +- src/guard/remove.rs | 4 +- src/guard/show.rs | 6 +- src/guard/update.rs | 4 +- src/guard/withdraw.rs | 4 +- src/lib.rs | 1 - src/main.rs | 37 +- src/mint/process.rs | 125 +- src/pdas.rs | 75 +- src/reveal/process.rs | 100 +- src/setup.rs | 15 +- src/show/process.rs | 54 +- src/sign/mod.rs | 3 - src/sign/process.rs | 195 --- src/update/mod.rs | 2 - src/update/process.rs | 14 +- src/update/set_token_standard.rs | 156 -- src/upload/assets.rs | 2 +- src/upload/methods/bundlr.rs | 4 +- src/upload/methods/shdw.rs | 2 +- src/upload/process.rs | 32 +- src/utils.rs | 105 +- src/validate/format.rs | 14 - src/validate/parser.rs | 22 - src/verify/process.rs | 17 +- src/withdraw/process.rs | 4 +- 52 files changed, 1757 insertions(+), 2091 deletions(-) delete mode 100644 src/sign/mod.rs delete mode 100644 src/sign/process.rs delete mode 100644 src/update/set_token_standard.rs diff --git a/.autodoc/docs/markdown/src/common.md b/.autodoc/docs/markdown/src/common.md index e1f5add5..edbbefbe 100644 --- a/.autodoc/docs/markdown/src/common.md +++ b/.autodoc/docs/markdown/src/common.md @@ -8,7 +8,7 @@ The code can be divided into three main sections: The code imports several components from Rust's standard library, such as `HashMap`, `File`, `Path`, `PathBuf`, and `FromStr`. These components are commonly used in various parts of the project for tasks like file handling, path manipulation, and string parsing. 2. External Library Imports: - The code imports components from several external libraries, such as `anchor_client`, `anchor_lang`, `anyhow`, `bs58`, `indexmap`, `mpl_candy_machine_core`, `reqwest`, `serde`, `serde_json`, and `tracing`. These libraries provide additional functionality for the project, such as interacting with the Solana blockchain (`anchor_client`), error handling (`anyhow`), HTTP requests (`reqwest`), and logging (`tracing`). + The code imports components from several external libraries, such as `anchor_client`, `anchor_lang`, `anyhow`, `bs58`, `indexmap`, `mpl_core_candy_machine_core`, `reqwest`, `serde`, `serde_json`, and `tracing`. These libraries provide additional functionality for the project, such as interacting with the Solana blockchain (`anchor_client`), error handling (`anyhow`), HTTP requests (`reqwest`), and logging (`tracing`). 3. Internal Module Imports: The code imports components from other modules within the Sugar project, such as `cache`, `constants`, `errors`, `parse`, and `setup`. These modules provide project-specific functionality, like caching data, defining constants, handling custom errors, parsing input, and setting up the project environment. @@ -20,8 +20,10 @@ let client = setup_client(...); ``` By organizing imports in this manner, the Sugar project can easily manage its dependencies and ensure that all required components are available for use throughout the codebase. -## Questions: - 1. **Question:** What is the purpose of the `sugar` project and how does this code fit into the overall project? + +## Questions: + +1. **Question:** What is the purpose of the `sugar` project and how does this code fit into the overall project? **Answer:** The purpose of the `sugar` project is not clear from this code snippet alone. This code appears to be a module that imports various external libraries and internal modules for use within the project, but more context is needed to understand the project's overall goal. @@ -31,4 +33,4 @@ By organizing imports in this manner, the Sugar project can easily manage its de 3. **Question:** Are there any specific version requirements for the imported libraries, and how can they be managed? - **Answer:** This code snippet does not provide information about specific version requirements for the imported libraries. Version management is typically handled in a separate configuration file, such as a `Cargo.toml` file for Rust projects. \ No newline at end of file + **Answer:** This code snippet does not provide information about specific version requirements for the imported libraries. Version management is typically handled in a separate configuration file, such as a `Cargo.toml` file for Rust projects. diff --git a/.autodoc/docs/markdown/src/config/guard_data.md b/.autodoc/docs/markdown/src/config/guard_data.md index f00d191b..342acda8 100644 --- a/.autodoc/docs/markdown/src/config/guard_data.md +++ b/.autodoc/docs/markdown/src/config/guard_data.md @@ -2,11 +2,11 @@ The code defines a set of data structures and methods for managing guards in the Sugar project. Guards are conditions that must be met for certain actions to be allowed, such as minting tokens or accessing specific features. The main data structure is `CandyGuardData`, which contains a default `GuardSet` and an optional list of `Group`s, each with its own `GuardSet`. -The `GuardSet` structure contains various optional guards, such as `BotTax`, `SolPayment`, `TokenPayment`, `StartDate`, `ThirdPartySigner`, `TokenGate`, `Gatekeeper`, `EndDate`, `AllowList`, `MintLimit`, `NftPayment`, `RedeemedAmount`, `AddressGate`, `NftGate`, `NftBurn`, `TokenBurn`, `FreezeSolPayment`, and `FreezeTokenPayment`. Each guard has its own data structure and a method `to_guard_format()` that converts it to the corresponding format used by the `mpl_candy_guard` library. +The `GuardSet` structure contains various optional guards, such as `BotTax`, `SolPayment`, `TokenPayment`, `StartDate`, `ThirdPartySigner`, `TokenGate`, `Gatekeeper`, `EndDate`, `AllowList`, `MintLimit`, `NftPayment`, `RedeemedAmount`, `AddressGate`, `NftGate`, `NftBurn`, `TokenBurn`, `FreezeSolPayment`, and `FreezeTokenPayment`. Each guard has its own data structure and a method `to_guard_format()` that converts it to the corresponding format used by the `mpl_core_candy_guard` library. -For example, the `BotTax` guard has a `value` field representing the penalty for invalid transactions and a `last_instruction` field indicating whether it should be checked as the last instruction. The `to_guard_format()` method converts the `value` to lamports and returns a `mpl_candy_guard::guards::BotTax` object. +For example, the `BotTax` guard has a `value` field representing the penalty for invalid transactions and a `last_instruction` field indicating whether it should be checked as the last instruction. The `to_guard_format()` method converts the `value` to lamports and returns a `mpl_core_candy_guard::guards::BotTax` object. -The `CandyGuardData` and `Group` structures also have `to_guard_format()` methods that convert their respective `GuardSet`s to the `mpl_candy_guard` format. +The `CandyGuardData` and `Group` structures also have `to_guard_format()` methods that convert their respective `GuardSet`s to the `mpl_core_candy_guard` format. Here's an example of how the code might be used in the larger project: @@ -21,19 +21,21 @@ let candy_guard_data = CandyGuardData { groups: None, }; -let mpl_candy_guard_data = candy_guard_data.to_guard_format()?; +let mpl_core_candy_guard_data = candy_guard_data.to_guard_format()?; ``` -This example creates a `CandyGuardData` object with a default `GuardSet` containing a `BotTax`, `SolPayment`, and `StartDate` guard. It then converts the `CandyGuardData` object to the `mpl_candy_guard` format. -## Questions: - 1. **What is the purpose of the `CandyGuardData` struct and its `to_guard_format` method?** +This example creates a `CandyGuardData` object with a default `GuardSet` containing a `BotTax`, `SolPayment`, and `StartDate` guard. It then converts the `CandyGuardData` object to the `mpl_core_candy_guard` format. - The `CandyGuardData` struct represents the data structure for a candy guard, which includes a default `GuardSet` and an optional vector of `Group` structs. The `to_guard_format` method converts the `CandyGuardData` into the format used by the `mpl_candy_guard::state::CandyGuardData` struct. +## Questions: + +1. **What is the purpose of the `CandyGuardData` struct and its `to_guard_format` method?** + +The `CandyGuardData` struct represents the data structure for a candy guard, which includes a default `GuardSet` and an optional vector of `Group` structs. The `to_guard_format` method converts the `CandyGuardData` into the format used by the `mpl_core_candy_guard::state::CandyGuardData` struct. 2. **What are the different types of guards available in the `GuardSet` struct?** The `GuardSet` struct contains various types of guards, such as `BotTax`, `SolPayment`, `TokenPayment`, `StartDate`, `ThirdPartySigner`, `TokenGate`, `Gatekeeper`, `EndDate`, `AllowList`, `MintLimit`, `NftPayment`, `RedeemedAmount`, `AddressGate`, `NftGate`, `NftBurn`, `TokenBurn`, `FreezeSolPayment`, and `FreezeTokenPayment`. -3. **How are the different guard structs converted to their corresponding `mpl_candy_guard::guards` format?** +3. **How are the different guard structs converted to their corresponding `mpl_core_candy_guard::guards` format?** - Each guard struct has a `to_guard_format` method that converts the struct into its corresponding `mpl_candy_guard::guards` format. For example, the `BotTax` struct's `to_guard_format` method returns a `mpl_candy_guard::guards::BotTax` struct with the same data. \ No newline at end of file + Each guard struct has a `to_guard_format` method that converts the struct into its corresponding `mpl_core_candy_guard::guards` format. For example, the `BotTax` struct's `to_guard_format` method returns a `mpl_core_candy_guard::guards::BotTax` struct with the same data. diff --git a/.autodoc/docs/markdown/src/config/summary.md b/.autodoc/docs/markdown/src/config/summary.md index 220016d0..7cb63e76 100644 --- a/.autodoc/docs/markdown/src/config/summary.md +++ b/.autodoc/docs/markdown/src/config/summary.md @@ -6,7 +6,7 @@ The `data.rs` file defines the main `ConfigData` structure, along with several o The `errors.rs` file defines a custom error type called `ConfigError` for handling configuration-related issues. It has seven variants, each representing a specific configuration error, such as `ParseError`, `MissingFileError`, `InvalidPathError`, and `PermissionError`. -The `guard_data.rs` file manages guards in the project, which are conditions that must be met for certain actions to be allowed. It defines the `CandyGuardData` structure, which contains a default `GuardSet` and an optional list of `Group`s, each with its own `GuardSet`. Each guard has its own data structure and a method `to_guard_format()` that converts it to the corresponding format used by the `mpl_candy_guard` library. +The `guard_data.rs` file manages guards in the project, which are conditions that must be met for certain actions to be allowed. It defines the `CandyGuardData` structure, which contains a default `GuardSet` and an optional list of `Group`s, each with its own `GuardSet`. Each guard has its own data structure and a method `to_guard_format()` that converts it to the corresponding format used by the `mpl_core_candy_guard` library. The `mod.rs` file imports and re-exports the contents of the `data`, `errors`, `guard_data`, and `parser` submodules, making them available for use in other parts of the project. It also defines three utility functions: `price_as_lamports`, `to_string`, and `to_pubkey`. diff --git a/.autodoc/docs/markdown/src/guard/remove.md b/.autodoc/docs/markdown/src/guard/remove.md index 76cdc0f5..049b3f4e 100644 --- a/.autodoc/docs/markdown/src/guard/remove.md +++ b/.autodoc/docs/markdown/src/guard/remove.md @@ -3,6 +3,7 @@ The `sugar` project contains a file that defines the functionality for removing a candy guard from a candy machine. The candy guard acts as a mint authority, controlling the creation of new tokens in the candy machine. This file provides a function `process_guard_remove` that takes a `GuardRemoveArgs` struct as an argument and returns a `Result<()>`. The `GuardRemoveArgs` struct contains the following fields: + - `keypair`: An optional string representing the user's keypair. - `rpc_url`: An optional string representing the RPC URL for the Solana network. - `cache`: A string representing the cache file path. @@ -10,6 +11,7 @@ The `GuardRemoveArgs` struct contains the following fields: - `candy_guard`: An optional string representing the candy guard ID. The `process_guard_remove` function performs the following steps: + 1. It prints a message indicating the unwrapping process has started. 2. It retrieves the candy machine ID and candy guard ID from the provided arguments or from the cache file. 3. It validates and converts the candy machine ID and candy guard ID into `Pubkey` objects. @@ -33,12 +35,14 @@ process_guard_remove(args)?; ``` This code would remove the specified candy guard as the mint authority of the specified candy machine, transferring the mint authority to the user's keypair. -## Questions: - 1. **Question:** What is the purpose of the `GuardRemoveArgs` struct and its fields? + +## Questions: + +1. **Question:** What is the purpose of the `GuardRemoveArgs` struct and its fields? **Answer:** The `GuardRemoveArgs` struct is used to store the arguments required for the `process_guard_remove` function. It contains fields for keypair, rpc_url, cache, candy_machine, and candy_guard, which are all optional strings. 2. **Question:** How does the code handle the precedence of candy machine and candy guard IDs specified in the arguments over the ones from the cache? **Answer:** The code checks if the candy machine or candy guard ID is provided in the arguments. If it is, the provided ID is used; otherwise, the ID is loaded from the cache. 3. **Question:** How does the code remove the candy guard as the mint authority? - **Answer:** The code sets up a client and a program with the `mpl_candy_guard::ID`. It then creates a transaction with the `UnwrapAccount` struct, which contains the necessary account information, and sends the transaction using `tx.send()`. This effectively removes the candy guard as the mint authority. \ No newline at end of file + **Answer:** The code sets up a client and a program with the `mpl_core_candy_guard::ID`. It then creates a transaction with the `UnwrapAccount` struct, which contains the necessary account information, and sends the transaction using `tx.send()`. This effectively removes the candy guard as the mint authority. diff --git a/.autodoc/docs/markdown/src/guard/withdraw.md b/.autodoc/docs/markdown/src/guard/withdraw.md index 484c5ebd..7696f93d 100644 --- a/.autodoc/docs/markdown/src/guard/withdraw.md +++ b/.autodoc/docs/markdown/src/guard/withdraw.md @@ -10,7 +10,7 @@ The `process_guard_withdraw` function performs the following steps: 3. Retrieve the candy guard account information: The function connects to the Solana network and retrieves the account information for the candy guard ID. -4. Withdraw funds from the candy guard account: The function creates a transaction to withdraw funds from the candy guard account using the `Withdraw` instruction from the `mpl_candy_guard` crate. The transaction is signed by the payer's keypair and sent to the network. +4. Withdraw funds from the candy guard account: The function creates a transaction to withdraw funds from the candy guard account using the `Withdraw` instruction from the `mpl_core_candy_guard` crate. The transaction is signed by the payer's keypair and sent to the network. 5. Update the cache: If the candy guard account was closed and its reference was stored in the cache, the function removes the reference from the cache and syncs the cache file. @@ -28,12 +28,14 @@ process_guard_withdraw(args)?; ``` This code snippet initializes a `GuardWithdrawArgs` struct with the necessary information and calls the `process_guard_withdraw` function to withdraw funds from the candy guard account. -## Questions: - 1. **Question:** What is the purpose of the `GuardWithdrawArgs` struct and what are its fields used for? + +## Questions: + +1. **Question:** What is the purpose of the `GuardWithdrawArgs` struct and what are its fields used for? **Answer:** The `GuardWithdrawArgs` struct is used to store the arguments required for the `process_guard_withdraw` function. It has fields for keypair, rpc_url, cache, and candy_guard, which store the user's keypair, the RPC URL for the Solana network, the cache file path, and the optional candy guard ID, respectively. 2. **Question:** How does the code handle the case when both `args.candy_guard` and the candy guard ID from the cache are provided? **Answer:** If both `args.candy_guard` and the candy guard ID from the cache are provided, the code prioritizes the `args.candy_guard` value and uses it for the withdrawal process, ignoring the one from the cache. 3. **Question:** What happens if the candy guard ID is not provided in the arguments or the cache? - **Answer:** If the candy guard ID is not provided in the arguments or the cache, the code returns an error with the message "Missing candy guard id." and the withdrawal process is not executed. \ No newline at end of file + **Answer:** If the candy guard ID is not provided in the arguments or the cache, the code returns an error with the message "Missing candy guard id." and the withdrawal process is not executed. diff --git a/Cargo.lock b/Cargo.lock index dae46613..e3daaf99 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,7 +49,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if", - "cipher 0.3.0", + "cipher", "cpufeatures", "opaque-debug", ] @@ -62,7 +62,7 @@ checksum = "589c637f0e68c877bbd59a4599bbe849cac8e5f3e4b5a3ebae8f528cd218dcdc" dependencies = [ "aead", "aes", - "cipher 0.3.0", + "cipher", "ctr", "polyval", "subtle", @@ -82,14 +82,15 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "72832d73be48bac96a5d7944568f305d829ed55b0ce3b483647089dfaf6cf704" dependencies = [ "cfg-if", "getrandom 0.2.10", "once_cell", "version_check", + "zerocopy 0.7.35", ] [[package]] @@ -118,9 +119,9 @@ dependencies = [ [[package]] name = "anchor-attribute-access-control" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d5e1a413b311b039d29b61d0dbb401c9dbf04f792497ceca87593454bf6d7dd" +checksum = "faa5be5b72abea167f87c868379ba3c2be356bfca9e6f474fd055fa0f7eeb4f2" dependencies = [ "anchor-syn", "anyhow", @@ -132,13 +133,13 @@ dependencies = [ [[package]] name = "anchor-attribute-account" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cca9aeaf633c6e2365fed0525dcac68610be58eee5dc69d3b86fe0b1d4b320b9" +checksum = "f468970344c7c9f9d03b4da854fd7c54f21305059f53789d0045c1dd803f0018" dependencies = [ "anchor-syn", "anyhow", - "bs58 0.4.0", + "bs58 0.5.1", "proc-macro2 1.0.67", "quote 1.0.33", "rustversion", @@ -147,9 +148,9 @@ dependencies = [ [[package]] name = "anchor-attribute-constant" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788e44f9e8501dabeb6f9229da0f3268fb2ae3208912608ffaa056a72031296f" +checksum = "59948e7f9ef8144c2aefb3f32a40c5fce2798baeec765ba038389e82301017ef" dependencies = [ "anchor-syn", "proc-macro2 1.0.67", @@ -158,9 +159,9 @@ dependencies = [ [[package]] name = "anchor-attribute-error" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c4d8c7e4a2605ede6fcdced9690288b2f74e24768619a85229d57e597bc97" +checksum = "fc753c9d1c7981cb8948cf7e162fb0f64558999c0413058e2d43df1df5448086" dependencies = [ "anchor-syn", "proc-macro2 1.0.67", @@ -170,9 +171,9 @@ dependencies = [ [[package]] name = "anchor-attribute-event" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a3b07d5c5d87b5edc72428b447b8e9ee1143b83dd1afc6a6b1d352c6a6164d8" +checksum = "f38b4e172ba1b52078f53fdc9f11e3dc0668ad27997838a0aad2d148afac8c97" dependencies = [ "anchor-syn", "anyhow", @@ -183,9 +184,9 @@ dependencies = [ [[package]] name = "anchor-attribute-program" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22ad0445115dbea5869b1d062da49ae125abed9132fc20c33227f25e42dfa6b" +checksum = "4eebd21543606ab61e2d83d9da37d24d3886a49f390f9c43a1964735e8c0f0d5" dependencies = [ "anchor-syn", "anyhow", @@ -196,26 +197,28 @@ dependencies = [ [[package]] name = "anchor-client" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c06e06497b5b4f392845e0d04dde8374fd244fa2832dd0e5c27bfd99cb0342" +checksum = "8434a6bf33efba0c93157f7fa2fafac658cb26ab75396886dcedd87c2a8ad445" dependencies = [ "anchor-lang", "anyhow", + "futures", "regex", "serde", "solana-account-decoder", "solana-client", "solana-sdk", "thiserror", + "tokio", "url", ] [[package]] name = "anchor-derive-accounts" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48daeff6781ba2f02961b0ad211feb9a2de75af345d42c62b1a252fd4dfb0724" +checksum = "ec4720d899b3686396cced9508f23dab420f1308344456ec78ef76f98fda42af" dependencies = [ "anchor-syn", "anyhow", @@ -226,9 +229,9 @@ dependencies = [ [[package]] name = "anchor-derive-space" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4fe2886f92c4f33ec1b2b8b2b43ca1b9070cf4929e63c7eaaa09a9f2c0d5123" +checksum = "f495e85480bd96ddeb77b71d499247c7d4e8b501e75ecb234e9ef7ae7bd6552a" dependencies = [ "proc-macro2 1.0.67", "quote 1.0.33", @@ -237,9 +240,9 @@ dependencies = [ [[package]] name = "anchor-lang" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbbe5d1c7c057c6d63b4f2f538a320e4a22111126c9966340c3d9490e2f15ed1" +checksum = "0d2d4b20100f1310a774aba3471ef268e5c4ba4d5c28c0bbe663c2658acbc414" dependencies = [ "anchor-attribute-access-control", "anchor-attribute-account", @@ -252,26 +255,27 @@ dependencies = [ "arrayref", "base64 0.13.1", "bincode", - "borsh", + "borsh 0.10.3", "bytemuck", + "getrandom 0.2.10", "solana-program", "thiserror", ] [[package]] name = "anchor-syn" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11cb31fe143aedb36fc41409ea072aa0b840cbea727e62eb2ff6e7b6cea036ff" +checksum = "a125e4b0cc046cfec58f5aa25038e34cf440151d58f0db3afc55308251fe936d" dependencies = [ "anyhow", - "bs58 0.3.1", + "bs58 0.5.1", "heck 0.3.3", "proc-macro2 1.0.67", "quote 1.0.33", "serde", "serde_json", - "sha2 0.9.9", + "sha2 0.10.7", "syn 1.0.109", "thiserror", ] @@ -306,6 +310,129 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest 0.10.7", + "itertools", + "num-bigint 0.4.4", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.4", + "num-traits", + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest 0.10.7", + "num-bigint 0.4.4", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "array-bytes" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ad284aeb45c13f2fb4f084de4a420ebf447423bdf9386c0540ce33cb3ef4b8c" + [[package]] name = "arrayref" version = "0.3.7" @@ -318,6 +445,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "ascii" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" + [[package]] name = "asn1-rs" version = "0.5.2" @@ -363,6 +496,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + [[package]] name = "async-compression" version = "0.4.3" @@ -482,7 +626,7 @@ dependencies = [ "thiserror", "typed-builder", "uuid", - "zerocopy", + "zerocopy 0.3.0", ] [[package]] @@ -543,6 +687,12 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "base64ct" version = "1.6.0" @@ -593,9 +743,9 @@ dependencies = [ [[package]] name = "blake3" -version = "1.3.1" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" dependencies = [ "arrayref", "arrayvec", @@ -636,18 +786,41 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" dependencies = [ - "borsh-derive", + "borsh-derive 0.9.3", "hashbrown 0.11.2", ] +[[package]] +name = "borsh" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4114279215a005bc675e386011e594e1d9b800918cea18fcadadcce864a2046b" +dependencies = [ + "borsh-derive 0.10.3", + "hashbrown 0.13.2", +] + [[package]] name = "borsh-derive" version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" dependencies = [ - "borsh-derive-internal", - "borsh-schema-derive-internal", + "borsh-derive-internal 0.9.3", + "borsh-schema-derive-internal 0.9.3", + "proc-macro-crate 0.1.5", + "proc-macro2 1.0.67", + "syn 1.0.109", +] + +[[package]] +name = "borsh-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0754613691538d51f329cce9af41d7b7ca150bc973056f1156611489475f54f7" +dependencies = [ + "borsh-derive-internal 0.10.3", + "borsh-schema-derive-internal 0.10.3", "proc-macro-crate 0.1.5", "proc-macro2 1.0.67", "syn 1.0.109", @@ -664,6 +837,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "borsh-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb438156919598d2c7bad7e1c0adf3d26ed3840dbc010db1a882a65583ca2fb" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "borsh-schema-derive-internal" version = "0.9.3" @@ -675,6 +859,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "borsh-schema-derive-internal" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634205cc43f74a1b9046ef87c4540ebda95696ec0f315024860cad7c5b0f5ccd" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "brotli" version = "3.3.4" @@ -698,15 +893,18 @@ dependencies = [ [[package]] name = "bs58" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bs58" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] [[package]] name = "bumpalo" @@ -732,7 +930,7 @@ dependencies = [ "ed25519-dalek", "futures", "lazy_static", - "num-derive", + "num-derive 0.3.3", "num-traits", "pipe", "primitive-types", @@ -857,16 +1055,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "clap" version = "2.34.0" @@ -921,6 +1109,28 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "combine" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" +dependencies = [ + "ascii", + "byteorder", + "either", + "memchr", + "unreachable", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "configparser" version = "1.0.0" @@ -968,9 +1178,9 @@ checksum = "e4c78c047431fee22c1a7bb92e00ad095a02a983affe4d8a72e2a2c62c1b94f3" [[package]] name = "constant_time_eq" -version = "0.1.5" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "convert_case" @@ -1087,7 +1297,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" dependencies = [ - "cipher 0.3.0", + "cipher", ] [[package]] @@ -1240,6 +1450,17 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e5c37193a1db1d8ed868c03ec7b152175f26160a5b740e5e484143877e0adf0" +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 1.0.109", +] + [[package]] name = "derive_builder" version = "0.10.2" @@ -1325,16 +1546,6 @@ dependencies = [ "dirs-sys", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.7" @@ -1346,17 +1557,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "displaydoc" version = "0.2.4" @@ -1461,31 +1661,19 @@ dependencies = [ [[package]] name = "enum-iterator" -version = "0.8.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2953d1df47ac0eb70086ccabf0275aa8da8591a28bd358ee2b52bd9f9e3ff9e9" +checksum = "9fd242f399be1da0a5354aa462d57b4ab2b4ee0683cc552f7c007d2d12d36e94" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8958699f9359f0b04e691a13850d48b7de329138023876d07cbd024c2c820598" -dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "syn 1.0.109", -] - -[[package]] -name = "enum_dispatch" -version = "0.3.12" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f33313078bb8d4d05a2733a94ac4c2d8a0df9a2b84424ebf4f33bfc224a890e" +checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ - "once_cell", "proc-macro2 1.0.67", "quote 1.0.33", "syn 2.0.33", @@ -1696,15 +1884,6 @@ dependencies = [ "slab", ] -[[package]] -name = "fxhash" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -dependencies = [ - "byteorder", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -1764,6 +1943,17 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "goblin" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7666983ed0dd8d21a6f6576ee00053ca0926fb281a5522577a4dbd0f1b54143" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "h2" version = "0.3.21" @@ -1783,6 +1973,15 @@ dependencies = [ "tracing", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hashbrown" version = "0.11.2" @@ -1801,6 +2000,15 @@ dependencies = [ "ahash 0.7.6", ] +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.4", +] + [[package]] name = "hashbrown" version = "0.14.0" @@ -2080,6 +2288,19 @@ dependencies = [ "regex", ] +[[package]] +name = "indicatif" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "763a5a8f45087d6bcea4222e7b72c291a054edf80e4ef6efd2a4979878c7bea3" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + [[package]] name = "ini" version = "1.3.0" @@ -2090,12 +2311,12 @@ dependencies = [ ] [[package]] -name = "inout" -version = "0.1.3" +name = "instant" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" dependencies = [ - "generic-array", + "cfg-if", ] [[package]] @@ -2163,9 +2384,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" @@ -2193,16 +2414,6 @@ dependencies = [ "rle-decode-fast", ] -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - [[package]] name = "libsecp256k1" version = "0.6.0" @@ -2322,9 +2533,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.6.5" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ "autocfg", ] @@ -2402,107 +2613,123 @@ dependencies = [ ] [[package]] -name = "mpl-candy-guard" -version = "1.1.0" +name = "modular-bitfield" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b216d92b0f9c776087e694a2469200ae26db7eda1426a66f9e7aad2d80d4a926" +checksum = "a53d79ba8304ac1c4f9eb3b9d281f21f7be9d4626f72ce7df4ad8fbde4f38a74" dependencies = [ - "anchor-lang", - "arrayref", - "mpl-candy-guard-derive", - "mpl-candy-machine-core", - "mpl-token-auth-rules", - "mpl-token-metadata", - "solana-gateway", - "solana-program", - "spl-associated-token-account", - "spl-token", - "spl-token-2022", + "modular-bitfield-impl", + "static_assertions", ] [[package]] -name = "mpl-candy-guard-derive" -version = "0.2.0" +name = "modular-bitfield-impl" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4d3002ea881e94a238798faf87a006a687297a24bd4b3f810fbb63611173d" +checksum = "5a7d5f7076603ebc68de2dc6a650ec331a062a13abaa346975be747bbfa4b789" dependencies = [ + "proc-macro2 1.0.67", "quote 1.0.33", "syn 1.0.109", ] [[package]] -name = "mpl-candy-machine-core" -version = "1.0.4" +name = "mpl-core" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf437d3876a6644bbebc1abcbfef4d999357fbe8a6f58c4d0b9055178904f136" +checksum = "de7477a52a59fe4db051c6a83077319288e8bfbd1aaf8511d4f733e3a77b6d24" dependencies = [ - "anchor-lang", - "arrayref", - "mpl-token-auth-rules", - "mpl-token-metadata", + "base64 0.22.1", + "borsh 0.10.3", + "num-derive 0.3.3", + "num-traits", "solana-program", - "spl-associated-token-account", - "spl-token", + "thiserror", ] [[package]] -name = "mpl-token-auth-rules" -version = "1.3.0" +name = "mpl-core" +version = "0.8.0-beta.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24dcb2b0ec0e9246f6f035e0336ba3359c21f6928dfd90281999e2c8e8ab53eb" +checksum = "1178d8a405352e2a2478abf5b62e2a4d6a91ed6f0470307ab6732614662dbf85" dependencies = [ - "borsh", - "mpl-token-metadata-context-derive", - "num-derive", + "base64 0.22.1", + "borsh 0.10.3", + "modular-bitfield", + "num-derive 0.3.3", "num-traits", "rmp-serde", - "serde", - "shank", + "serde_json", "solana-program", - "solana-zk-token-sdk", "thiserror", ] [[package]] -name = "mpl-token-metadata" -version = "1.9.1" +name = "mpl-core-candy-guard" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "410acbbc7d543108cc4d93f98290da008716c801f04a923cd83de2ec86244c1f" +checksum = "03f3121ef1227199f48861fcb13d233d4913fa57cd5df38f693c6b856ddff9b7" dependencies = [ + "anchor-lang", "arrayref", - "borsh", - "mpl-token-auth-rules", - "mpl-token-metadata-context-derive", - "mpl-utils", - "num-derive", - "num-traits", - "shank", + "mpl-core 0.4.4", + "mpl-core-candy-guard-derive", + "mpl-core-candy-machine-core", + "mpl-token-metadata", + "solana-gateway", "solana-program", - "spl-associated-token-account", - "spl-token", - "thiserror", + "spl-associated-token-account 2.2.0", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", ] [[package]] -name = "mpl-token-metadata-context-derive" +name = "mpl-core-candy-guard-derive" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12989bc45715b0ee91944855130131479f9c772e198a910c3eb0ea327d5bffc3" +checksum = "fce1596e434a29efea87f8bf1a457109393b3dad33cbc06268bc6a0b0b0e862b" dependencies = [ "quote 1.0.33", "syn 1.0.109", ] +[[package]] +name = "mpl-core-candy-machine-core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62a42bd1df60a6b03189957c81614d1f0e607e09210a9d223a908ddbd98c08b1" +dependencies = [ + "anchor-lang", + "arrayref", + "mpl-core 0.4.4", + "mpl-token-metadata", + "mpl-utils", + "solana-program", + "spl-associated-token-account 2.2.0", + "spl-token 4.0.0", +] + +[[package]] +name = "mpl-token-metadata" +version = "3.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba8ee05284d79b367ae8966d558e1a305a781fc80c9df51f37775169117ba64f" +dependencies = [ + "borsh 0.10.3", + "num-derive 0.3.3", + "num-traits", + "solana-program", + "thiserror", +] + [[package]] name = "mpl-utils" -version = "0.1.0" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc48e64c50dba956acb46eec86d6968ef0401ef37031426da479f1f2b592066" +checksum = "8ee1b830bfd014504a11b2234e2e7d6af535adda601f224cd519b923f593c91b" dependencies = [ "arrayref", - "borsh", "solana-program", - "spl-token", ] [[package]] @@ -2525,14 +2752,15 @@ dependencies = [ [[package]] name = "nix" -version = "0.24.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" dependencies = [ "bitflags 1.3.2", "cfg-if", "libc", - "memoffset 0.6.5", + "memoffset 0.7.1", + "pin-utils", ] [[package]] @@ -2623,6 +2851,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 2.0.33", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -2681,7 +2920,25 @@ version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.5.11", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive 0.7.3", ] [[package]] @@ -2696,6 +2953,30 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 2.0.33", +] + [[package]] name = "number_prefix" version = "0.4.0" @@ -2988,6 +3269,12 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "polyval" version = "0.5.3" @@ -3000,6 +3287,12 @@ dependencies = [ "universal-hash", ] +[[package]] +name = "portable-atomic" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" + [[package]] name = "ppv-lite86" version = "0.2.17" @@ -3104,16 +3397,15 @@ dependencies = [ [[package]] name = "quinn" -version = "0.8.5" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b435e71d9bfa0d8889927231970c51fb89c58fa63bffcab117c9c7a41e5ef8f" +checksum = "2e8b432585672228923edbbf64b8b12c14e1112f62e88737655b4a083dbcd78e" dependencies = [ "bytes", - "futures-channel", - "futures-util", - "fxhash", + "pin-project-lite", "quinn-proto", "quinn-udp", + "rustc-hash", "rustls 0.20.9", "thiserror", "tokio", @@ -3123,17 +3415,16 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.8.4" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fce546b9688f767a57530652488420d419a8b1f44a478b451c3d1ab6d992a55" +checksum = "94b0b33c13a79f669c85defaf4c275dc86a0c0372807d0ca3d78e0bb87274863" dependencies = [ "bytes", - "fxhash", "rand 0.8.5", "ring", + "rustc-hash", "rustls 0.20.9", "rustls-native-certs", - "rustls-pemfile 0.2.1", "slab", "thiserror", "tinyvec", @@ -3143,16 +3434,15 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.1.4" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07946277141531aea269befd949ed16b2c85a780ba1043244eda0969e538e54" +checksum = "641538578b21f5e5c8ea733b736895576d0fe329bb883b937db6f4d163dbaaf4" dependencies = [ - "futures-util", "libc", "quinn-proto", "socket2 0.4.9", - "tokio", "tracing", + "windows-sys 0.42.0", ] [[package]] @@ -3283,9 +3573,9 @@ dependencies = [ [[package]] name = "rcgen" -version = "0.9.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" +checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", @@ -3394,7 +3684,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls 0.21.7", - "rustls-pemfile 1.0.3", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", @@ -3466,14 +3756,23 @@ dependencies = [ [[package]] name = "rpassword" -version = "6.0.1" +version = "7.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf099a1888612545b683d2661a1940089f6c2e5a8e38979b2159da876bfd956" +checksum = "80472be3c897911d0137b2d2b9055faf6eeac5b14e324073d83bc17b191d7e3f" dependencies = [ "libc", - "serde", - "serde_json", - "winapi", + "rtoolbox", + "windows-sys 0.48.0", +] + +[[package]] +name = "rtoolbox" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c247d24e63230cdb56463ae328478bd5eac8b8faa8c69461a77e8e323afac90e" +dependencies = [ + "libc", + "windows-sys 0.48.0", ] [[package]] @@ -3597,20 +3896,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" dependencies = [ "openssl-probe", - "rustls-pemfile 1.0.3", + "rustls-pemfile", "schannel", "security-framework", ] -[[package]] -name = "rustls-pemfile" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" -dependencies = [ - "base64 0.13.1", -] - [[package]] name = "rustls-pemfile" version = "1.0.3" @@ -3657,6 +3947,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 2.0.33", +] + [[package]] name = "sct" version = "0.7.0" @@ -3760,6 +4070,16 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_with" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" +dependencies = [ + "serde", + "serde_with_macros 2.3.3", +] + [[package]] name = "serde_with" version = "3.3.0" @@ -3773,10 +4093,22 @@ dependencies = [ "indexmap 2.0.0", "serde", "serde_json", - "serde_with_macros", + "serde_with_macros 3.3.0", "time", ] +[[package]] +name = "serde_with_macros" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" +dependencies = [ + "darling 0.20.3", + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 2.0.33", +] + [[package]] name = "serde_with_macros" version = "3.3.0" @@ -3858,40 +4190,6 @@ dependencies = [ "keccak", ] -[[package]] -name = "shank" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63e565b5e95ad88ab38f312e89444c749360641c509ef2de0093b49f55974a5" -dependencies = [ - "shank_macro", -] - -[[package]] -name = "shank_macro" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63927d22a1e8b74bda98cc6e151fcdf178b7abb0dc6c4f81e0bbf5ffe2fc4ec8" -dependencies = [ - "proc-macro2 1.0.67", - "quote 1.0.33", - "shank_macro_impl", - "syn 1.0.109", -] - -[[package]] -name = "shank_macro_impl" -version = "0.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce03403df682f80f4dc1efafa87a4d0cb89b03726d0565e6364bdca5b9a441" -dependencies = [ - "anyhow", - "proc-macro2 1.0.67", - "quote 1.0.33", - "serde", - "syn 1.0.109", -] - [[package]] name = "sharded-slab" version = "0.1.4" @@ -3982,27 +4280,14 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "sol-did" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2546d424d6898908c205d99d3af07ad42e2e8aec8f0d459235dc0bd4e9866fe" -dependencies = [ - "borsh", - "num-derive", - "num-traits", - "solana-program", - "thiserror", -] - [[package]] name = "solana-account-decoder" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714067d617d791bbfc3c4fd30de9e18e7b5f29b5c0853b1a17581a3e88389e71" +checksum = "57a23e502edf181ac548d05d0e0c29aa4285e05cf082fcc66c9315fe3d1a89bc" dependencies = [ "Inflector", - "base64 0.13.1", + "base64 0.21.4", "bincode", "bs58 0.4.0", "bv", @@ -4013,23 +4298,23 @@ dependencies = [ "solana-address-lookup-table-program", "solana-config-program", "solana-sdk", - "solana-vote-program", - "spl-token", - "spl-token-2022", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", + "spl-token-metadata-interface", "thiserror", "zstd", ] [[package]] name = "solana-address-lookup-table-program" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3de77d93db1d7bdf5854c0cad36acb21cf6c44d3119834241e64e6916c92f232" +checksum = "5cf919521094c0489485589d01674e993ebb1d518abc8da439e31d7f5a72406f" dependencies = [ "bincode", "bytemuck", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -4043,9 +4328,9 @@ dependencies = [ [[package]] name = "solana-clap-utils" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a68198e8909cf912aa727e2f9f0b9ed7e6fecd330a8ad99c9e9ebe6d1a9a3ba" +checksum = "4af272571b1bcdbcd0096ba11b8f37f0d79d7118aedca753b8c4c52e1a69e8bf" dependencies = [ "chrono", "clap 2.34.0", @@ -4059,81 +4344,44 @@ dependencies = [ "url", ] -[[package]] -name = "solana-cli-config" -version = "1.14.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b74868956b9fb8d13fdc7710e4a7e7fec321e8698e777cc7c063686c7b14e0" -dependencies = [ - "dirs-next", - "lazy_static", - "serde", - "serde_derive", - "serde_yaml", - "solana-clap-utils", - "solana-sdk", - "url", -] - [[package]] name = "solana-client" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e076aa655a745d4d9455e61280568aa86f403022747c680ce54dcd1ce0f3cb95" +checksum = "0e626e74c0084e7d42d232aa1c20afcd78663abab19f19f349aba714f82aa13a" dependencies = [ - "async-mutex", "async-trait", - "base64 0.13.1", "bincode", - "bs58 0.4.0", - "bytes", - "clap 2.34.0", - "crossbeam-channel", - "enum_dispatch", "futures", "futures-util", "indexmap 1.9.3", - "indicatif", - "itertools", - "jsonrpc-core", - "lazy_static", + "indicatif 0.17.8", "log", "quinn", - "quinn-proto", "rand 0.7.3", - "rand_chacha 0.2.2", "rayon", - "reqwest", - "rustls 0.20.9", - "semver", - "serde", - "serde_derive", - "serde_json", - "solana-account-decoder", - "solana-clap-utils", - "solana-faucet", + "solana-connection-cache", "solana-measure", "solana-metrics", - "solana-net-utils", + "solana-pubsub-client", + "solana-quic-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-rpc-client-nonce-utils", "solana-sdk", "solana-streamer", - "solana-transaction-status", - "solana-version", - "solana-vote-program", - "spl-token-2022", + "solana-thin-client", + "solana-tpu-client", + "solana-udp-client", "thiserror", "tokio", - "tokio-stream", - "tokio-tungstenite", - "tungstenite", - "url", ] [[package]] name = "solana-config-program" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfadb7f09be905a08ed50090436c2e6e4bab17a84b8a4e03a94d79e5ce1693e" +checksum = "96f0a4b21581e08419c27458f275bb24bf9b70990756d1ca13c3ef21c56f2750" dependencies = [ "bincode", "chrono", @@ -4144,38 +4392,35 @@ dependencies = [ ] [[package]] -name = "solana-faucet" -version = "1.14.24" +name = "solana-connection-cache" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d9e45fb47f142f4ce69acffa4c942d64d96c6d43b24785813d1bdbb90d62833" +checksum = "ad1e97478ee9a977079863c2530fd4543d9a6e5f1c7fb306fa1557d9c72506b5" dependencies = [ + "async-trait", "bincode", - "byteorder", - "clap 2.34.0", - "crossbeam-channel", + "futures-util", + "indexmap 1.9.3", "log", - "serde", - "serde_derive", - "solana-clap-utils", - "solana-cli-config", - "solana-logger", + "rand 0.7.3", + "rayon", + "rcgen", + "solana-measure", "solana-metrics", "solana-sdk", - "solana-version", - "spl-memo", "thiserror", "tokio", ] [[package]] name = "solana-frozen-abi" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63117658963482734ad016e6b94d2d74599ad0f591ca63d5e0f831e233a85cdb" +checksum = "67a96a0a64cbc75e06c8eb49d6cd0a87054c48dbf59100d9959389aba51fb501" dependencies = [ - "ahash 0.7.6", + "ahash 0.8.4", "blake3", - "block-buffer 0.9.0", + "block-buffer 0.10.4", "bs58 0.4.0", "bv", "byteorder", @@ -4183,7 +4428,6 @@ dependencies = [ "either", "generic-array", "getrandom 0.1.16", - "hashbrown 0.12.3", "im", "lazy_static", "log", @@ -4203,36 +4447,34 @@ dependencies = [ [[package]] name = "solana-frozen-abi-macro" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9eca469f181dcc35c81fb9e0c31c37d0d9abd13805e7cd82446b843a0232246" +checksum = "5ae9765c963bebbf609dcdc82cfb969746cbdf6d65cfc9d94112e984475ae4ac" dependencies = [ "proc-macro2 1.0.67", "quote 1.0.33", "rustc_version", - "syn 1.0.109", + "syn 2.0.33", ] [[package]] name = "solana-gateway" -version = "0.2.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243daaf437dff89891d520c3e9be7b4a6940c30a1bda2ac094e621046f303eda" +checksum = "2d148eb75d0799f6825dc2a840b85c065e3d6d12212845add3e059163f98770e" dependencies = [ - "bitflags 1.3.2", - "borsh", - "num-derive", + "borsh 0.10.3", + "num-derive 0.4.2", "num-traits", - "sol-did", "solana-program", "thiserror", ] [[package]] name = "solana-logger" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6356aa0978dcdac6404fca123fbfa4c3a329e609fa9921d0e2d8c8cdd921cb" +checksum = "9c039e4336890c7a0667207caeb452187efa0602d80eca61a854f2e39915e972" dependencies = [ "env_logger", "lazy_static", @@ -4241,9 +4483,9 @@ dependencies = [ [[package]] name = "solana-measure" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f84a46c881fc5ea3b955d1f2313ffa477aab3ec501782a1387319d2e2376d97" +checksum = "4f188a8cf40c33a33cdf5396af88df194648ef52914fcfb5ce81e4cf03ab99ff" dependencies = [ "log", "solana-sdk", @@ -4251,9 +4493,9 @@ dependencies = [ [[package]] name = "solana-metrics" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39d25eb6904dd33790f4fe47e48171677fd5402a2df2d82aee5453679ea46774" +checksum = "7b0e6253c106dbe0a6736c9b6929b8284aa959f79486006330884252e486b515" dependencies = [ "crossbeam-channel", "gethostname", @@ -4265,15 +4507,15 @@ dependencies = [ [[package]] name = "solana-net-utils" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec98e671c2dbf742a698674e1f5e34121c2b9c0af661a261413b55bdab62aebc" +checksum = "7d33faefadf14f19710e5229a2f812a4ea3c1b173ca0043225761de663feab35" dependencies = [ "bincode", "clap 3.2.25", "crossbeam-channel", "log", - "nix 0.24.3", + "nix 0.26.4", "rand 0.7.3", "serde", "serde_derive", @@ -4287,11 +4529,11 @@ dependencies = [ [[package]] name = "solana-perf" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c44da6dab9e9669c28a2ce6b700c4da97d4243f108cf222ee2cfebd6ea41fce5" +checksum = "9a3a8b766c9ee568681462592f89161628e0a4493ed1b6a5a5c8cf3b94c80b98" dependencies = [ - "ahash 0.7.6", + "ahash 0.8.4", "bincode", "bv", "caps", @@ -4302,7 +4544,7 @@ dependencies = [ "lazy_static", "libc", "log", - "nix 0.24.3", + "nix 0.26.4", "rand 0.7.3", "rayon", "serde", @@ -4314,16 +4556,21 @@ dependencies = [ [[package]] name = "solana-program" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8481b0678be8450c423686483319076b2babf11f08cbc48aa6fae9f5cf1232ca" +checksum = "20c16757f43d4384907f6e81924e155b8bd8228efcdcf9ea38bd4e18ea100804" dependencies = [ - "base64 0.13.1", + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "array-bytes", + "base64 0.21.4", "bincode", "bitflags 1.3.2", "blake3", - "borsh", - "borsh-derive", + "borsh 0.10.3", + "borsh 0.9.3", "bs58 0.4.0", "bv", "bytemuck", @@ -4338,8 +4585,9 @@ dependencies = [ "libc", "libsecp256k1", "log", - "memoffset 0.6.5", - "num-derive", + "memoffset 0.9.0", + "num-bigint 0.4.4", + "num-derive 0.3.3", "num-traits", "parking_lot", "rand 0.7.3", @@ -4363,20 +4611,20 @@ dependencies = [ [[package]] name = "solana-program-runtime" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b59b03f3fc3f27f9bac7e2d79923b9b9cde9a77bf9272724fc75f6a78af757" +checksum = "7bd12d233724478c7ccf84d953a4abe891552d78bd41e2c594c098f76dde5a06" dependencies = [ - "base64 0.13.1", + "base64 0.21.4", "bincode", "eager", "enum-iterator", "itertools", "libc", - "libloading", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", + "percentage", "rand 0.7.3", "rustc_version", "serde", @@ -4385,14 +4633,68 @@ dependencies = [ "solana-measure", "solana-metrics", "solana-sdk", + "solana_rbpf", "thiserror", ] +[[package]] +name = "solana-pubsub-client" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "319fcfa162e2d01baf890986d1c9fc549acfdac19e0de07da80a7ef591aa1241" +dependencies = [ + "crossbeam-channel", + "futures-util", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", +] + +[[package]] +name = "solana-quic-client" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f88f6f70a2b0541855467cd3ead7631e7c4132e7f327965dae0d9649522acb3a" +dependencies = [ + "async-mutex", + "async-trait", + "futures", + "itertools", + "lazy_static", + "log", + "quinn", + "quinn-proto", + "quinn-udp", + "rcgen", + "rustls 0.20.9", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-net-utils", + "solana-rpc-client-api", + "solana-sdk", + "solana-streamer", + "thiserror", + "tokio", +] + [[package]] name = "solana-rayon-threadlimit" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f38eab4498e4f2764fb9a833383f35cf39a6f27249aa00b6b2759c6bc61d750" +checksum = "e2ba72e563531528d6e36090477d6b638ba1dfdbe04e6a97bf9e5a9f46e90837" dependencies = [ "lazy_static", "num_cpus", @@ -4400,14 +4702,14 @@ dependencies = [ [[package]] name = "solana-remote-wallet" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7466a3cf31c68fc38319aab88704162cefd80a5449a05486b5d7713376b620" +checksum = "1924c23c5a1ca48e1d285b43d2bfe351ac9de3a93b46a2f34972cba8a3688934" dependencies = [ "console", "dialoguer", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "parking_lot", "qstring", @@ -4417,17 +4719,78 @@ dependencies = [ "uriparse", ] +[[package]] +name = "solana-rpc-client" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "981e4cd5d5184e566568e16ed59dde6ee9f88b62fe2f0b25d72873af0302b354" +dependencies = [ + "async-trait", + "base64 0.21.4", + "bincode", + "bs58 0.4.0", + "indicatif 0.17.8", + "log", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-rpc-client-api", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "solana-vote-program", + "tokio", +] + +[[package]] +name = "solana-rpc-client-api" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e894b7a7025c782f97967b071d84f9219bb6ce53ef0794c756af9cc8bde5833e" +dependencies = [ + "base64 0.21.4", + "bs58 0.4.0", + "jsonrpc-core", + "reqwest", + "semver", + "serde", + "serde_derive", + "serde_json", + "solana-account-decoder", + "solana-sdk", + "solana-transaction-status", + "solana-version", + "spl-token-2022 0.9.0", + "thiserror", +] + +[[package]] +name = "solana-rpc-client-nonce-utils" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d69307d1f7fb297ea82e25d9cd1d83297140ce872009557fd57763511497cb5" +dependencies = [ + "clap 2.34.0", + "solana-clap-utils", + "solana-rpc-client", + "solana-sdk", + "thiserror", +] + [[package]] name = "solana-sdk" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67eb3cfd29f62d776fa248d57b730da8d927fa83c81b50cc6683b3f80c87429" +checksum = "cdf179cda65775982e5f31da8d58dfa4349c3b5ae1573ceb507c7fc91df66690" dependencies = [ "assert_matches", - "base64 0.13.1", + "base64 0.21.4", "bincode", "bitflags 1.3.2", - "borsh", + "borsh 0.10.3", "bs58 0.4.0", "bytemuck", "byteorder", @@ -4444,8 +4807,9 @@ dependencies = [ "libsecp256k1", "log", "memmap2", - "num-derive", + "num-derive 0.3.3", "num-traits", + "num_enum 0.6.1", "pbkdf2 0.11.0", "qstring", "rand 0.7.3", @@ -4456,6 +4820,7 @@ dependencies = [ "serde_bytes", "serde_derive", "serde_json", + "serde_with 2.3.3", "sha2 0.10.7", "sha3 0.10.8", "solana-frozen-abi", @@ -4470,23 +4835,25 @@ dependencies = [ [[package]] name = "solana-sdk-macro" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9a86d529a78915940dcbdfd46d07fa7d64ac0e57a2688d7201fff5a55318653" +checksum = "7f188d6fe76183137a4922274acbe76fc4fcc474b3fad860bb2612cb225e6e2a" dependencies = [ "bs58 0.4.0", "proc-macro2 1.0.67", "quote 1.0.33", "rustversion", - "syn 1.0.109", + "syn 2.0.33", ] [[package]] name = "solana-streamer" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2959ab13acac7866b2c6b18cfb69d9d854671ae366cc09125767922f39dd81ad" +checksum = "69308e9f79ff1e7ca55d32e5521ab1b11e5812830c8e3733dfa0a7021c6ddb24" dependencies = [ + "async-channel", + "bytes", "crossbeam-channel", "futures-util", "histogram", @@ -4494,11 +4861,13 @@ dependencies = [ "itertools", "libc", "log", - "nix 0.24.3", + "nix 0.26.4", "pem", "percentage", "pkcs8", "quinn", + "quinn-proto", + "quinn-udp", "rand 0.7.3", "rcgen", "rustls 0.20.9", @@ -4510,16 +4879,56 @@ dependencies = [ "x509-parser", ] +[[package]] +name = "solana-thin-client" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27fe04e9479ba32c2b07a75975458b71abefde1a0a2ba23bbcdb4a0134234ef2" +dependencies = [ + "bincode", + "log", + "rayon", + "solana-connection-cache", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", +] + +[[package]] +name = "solana-tpu-client" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf5abc9d7b1071f978d231bcb184c801008415d9917bad48c08b09c538a9ee30" +dependencies = [ + "async-trait", + "bincode", + "futures-util", + "indexmap 1.9.3", + "indicatif 0.17.8", + "log", + "rand 0.7.3", + "rayon", + "solana-connection-cache", + "solana-measure", + "solana-metrics", + "solana-pubsub-client", + "solana-rpc-client", + "solana-rpc-client-api", + "solana-sdk", + "thiserror", + "tokio", +] + [[package]] name = "solana-transaction-status" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e8031a9c3bdc2488bdd8223d0dcc879960310be8b25f1296308cf2b4d9e02d0" +checksum = "dff2f528270e438cd30b47ae81fc14b40162bc67794a65e30abec769322daeaf" dependencies = [ "Inflector", - "base64 0.13.1", + "base64 0.21.4", "bincode", - "borsh", + "borsh 0.10.3", "bs58 0.4.0", "lazy_static", "log", @@ -4528,22 +4937,34 @@ dependencies = [ "serde_json", "solana-account-decoder", "solana-address-lookup-table-program", - "solana-measure", - "solana-metrics", "solana-sdk", - "solana-vote-program", - "spl-associated-token-account", - "spl-memo", - "spl-token", - "spl-token-2022", + "spl-associated-token-account 2.2.0", + "spl-memo 4.0.0", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", + "thiserror", +] + +[[package]] +name = "solana-udp-client" +version = "1.16.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8723428368dd66b462a1e8ccd98c8d8bb020ad9dfbd051ed31a39857f89c17d" +dependencies = [ + "async-trait", + "solana-connection-cache", + "solana-net-utils", + "solana-sdk", + "solana-streamer", "thiserror", + "tokio", ] [[package]] name = "solana-version" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252ad2a1ff40cf7b09285af6b6f5922267b04eab8cae0290f8caf29c281b12e" +checksum = "a20bbadb84e29d645ae2d252a28eb0c7a98d656608ffcbab5a3b18cf5d509733" dependencies = [ "log", "rustc_version", @@ -4557,13 +4978,13 @@ dependencies = [ [[package]] name = "solana-vote-program" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61bb156d6953023d59b2473d18cdb135b4b26eef94e669a9ee3d412edeb6d1f8" +checksum = "ee544e1d43fde9135dfbc43707f1874dd2c44f5d786d9fd6077b5e57ae602109" dependencies = [ "bincode", "log", - "num-derive", + "num-derive 0.3.3", "num-traits", "rustc_version", "serde", @@ -4571,6 +4992,7 @@ dependencies = [ "solana-frozen-abi", "solana-frozen-abi-macro", "solana-metrics", + "solana-program", "solana-program-runtime", "solana-sdk", "thiserror", @@ -4578,23 +5000,21 @@ dependencies = [ [[package]] name = "solana-zk-token-sdk" -version = "1.14.24" +version = "1.16.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2853efabded5dce340cb67dc1f28f6db75dac219d9d9142d81073e2c43c9b7a" +checksum = "9513c4f1595b61f8a39a14c27535da2b2145c20c6b35ab491a1830981972b2bd" dependencies = [ "aes-gcm-siv", - "arrayref", - "base64 0.13.1", + "base64 0.21.4", "bincode", "bytemuck", "byteorder", - "cipher 0.4.4", "curve25519-dalek", "getrandom 0.1.16", "itertools", "lazy_static", "merlin", - "num-derive", + "num-derive 0.3.3", "num-traits", "rand 0.7.3", "serde", @@ -4607,6 +5027,25 @@ dependencies = [ "zeroize", ] +[[package]] +name = "solana_rbpf" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17d4ba1e58947346e360fabde0697029d36ba83c42f669199b16a8931313cf29" +dependencies = [ + "byteorder", + "combine", + "goblin", + "hash32", + "libc", + "log", + "rand 0.8.5", + "rustc-demangle", + "scroll", + "thiserror", + "winapi", +] + [[package]] name = "spin" version = "0.5.2" @@ -4630,12 +5069,63 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978dba3bcbe88d0c2c58366c254d9ea41c5f73357e72fc0bdee4d6b5fc99c8f4" dependencies = [ "assert_matches", - "borsh", - "num-derive", + "borsh 0.9.3", + "num-derive 0.3.3", "num-traits", "solana-program", - "spl-token", - "spl-token-2022", + "spl-token 3.5.0", + "spl-token-2022 0.6.1", + "thiserror", +] + +[[package]] +name = "spl-associated-token-account" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385e31c29981488f2820b2022d8e731aae3b02e6e18e2fd854e4c9a94dc44fc3" +dependencies = [ + "assert_matches", + "borsh 0.10.3", + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-token 4.0.0", + "spl-token-2022 0.9.0", + "thiserror", +] + +[[package]] +name = "spl-discriminator" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cce5d563b58ef1bb2cdbbfe0dfb9ffdc24903b10ae6a4df2d8f425ece375033f" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator-derive", +] + +[[package]] +name = "spl-discriminator-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07fd7858fc4ff8fb0e34090e41d7eb06a823e1057945c26d480bfc21d2338a93" +dependencies = [ + "quote 1.0.33", + "spl-discriminator-syn", + "syn 2.0.33", +] + +[[package]] +name = "spl-discriminator-syn" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fea7be851bd98d10721782ea958097c03a0c2a07d8d4997041d0ece6319a63" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "sha2 0.10.7", + "syn 2.0.33", "thiserror", ] @@ -4648,6 +5138,67 @@ dependencies = [ "solana-program", ] +[[package]] +name = "spl-memo" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f180b03318c3dbab3ef4e1e4d46d5211ae3c780940dd0a28695aba4b59a75a" +dependencies = [ + "solana-program", +] + +[[package]] +name = "spl-pod" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2881dddfca792737c0706fa0175345ab282b1b0879c7d877bad129645737c079" +dependencies = [ + "borsh 0.10.3", + "bytemuck", + "solana-program", + "solana-zk-token-sdk", + "spl-program-error", +] + +[[package]] +name = "spl-program-error" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "249e0318493b6bcf27ae9902600566c689b7dfba9f1bdff5893e92253374e78c" +dependencies = [ + "num-derive 0.4.2", + "num-traits", + "solana-program", + "spl-program-error-derive", + "thiserror", +] + +[[package]] +name = "spl-program-error-derive" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1845dfe71fd68f70382232742e758557afe973ae19e6c06807b2c30f5d5cb474" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "sha2 0.10.7", + "syn 2.0.33", +] + +[[package]] +name = "spl-tlv-account-resolution" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "062e148d3eab7b165582757453632ffeef490c02c86a48bfdb4988f63eefb3b9" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + [[package]] name = "spl-token" version = "3.5.0" @@ -4656,9 +5207,24 @@ checksum = "8e85e168a785e82564160dcb87b2a8e04cee9bfd1f4d488c729d53d6a4bd300d" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.3.3", "num-traits", - "num_enum", + "num_enum 0.5.11", + "solana-program", + "thiserror", +] + +[[package]] +name = "spl-token" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08459ba1b8f7c1020b4582c4edf0f5c7511a5e099a7a97570c9698d4f2337060" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.3.3", + "num-traits", + "num_enum 0.6.1", "solana-program", "thiserror", ] @@ -4671,16 +5237,81 @@ checksum = "0043b590232c400bad5ee9eb983ced003d15163c4c5d56b090ac6d9a57457b47" dependencies = [ "arrayref", "bytemuck", - "num-derive", + "num-derive 0.3.3", "num-traits", - "num_enum", + "num_enum 0.5.11", "solana-program", "solana-zk-token-sdk", - "spl-memo", - "spl-token", + "spl-memo 3.0.1", + "spl-token 3.5.0", "thiserror", ] +[[package]] +name = "spl-token-2022" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4abf34a65ba420584a0c35f3903f8d727d1f13ababbdc3f714c6b065a686e86" +dependencies = [ + "arrayref", + "bytemuck", + "num-derive 0.4.2", + "num-traits", + "num_enum 0.7.3", + "solana-program", + "solana-zk-token-sdk", + "spl-memo 4.0.0", + "spl-pod", + "spl-token 4.0.0", + "spl-token-metadata-interface", + "spl-transfer-hook-interface", + "spl-type-length-value", + "thiserror", +] + +[[package]] +name = "spl-token-metadata-interface" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c16ce3ba6979645fb7627aa1e435576172dd63088dc7848cb09aa331fa1fe4f" +dependencies = [ + "borsh 0.10.3", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-type-length-value", +] + +[[package]] +name = "spl-transfer-hook-interface" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "051d31803f873cabe71aec3c1b849f35248beae5d19a347d93a5c9cccc5d5a9b" +dependencies = [ + "arrayref", + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", + "spl-tlv-account-resolution", + "spl-type-length-value", +] + +[[package]] +name = "spl-type-length-value" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a468e6f6371f9c69aae760186ea9f1a01c2908351b06a5e0026d21cfc4d7ecac" +dependencies = [ + "bytemuck", + "solana-program", + "spl-discriminator", + "spl-pod", + "spl-program-error", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -4731,7 +5362,7 @@ dependencies = [ "anchor-lang", "anyhow", "async-trait", - "borsh", + "borsh 0.9.3", "bs58 0.4.0", "bundlr-sdk", "cargo-husky", @@ -4747,13 +5378,12 @@ dependencies = [ "glob", "hex", "indexmap 1.9.3", - "indicatif", + "indicatif 0.16.2", "ini", "lazy_static", - "mpl-candy-guard", - "mpl-candy-machine-core", - "mpl-token-auth-rules", - "mpl-token-metadata", + "mpl-core 0.8.0-beta.1", + "mpl-core-candy-guard", + "mpl-core-candy-machine-core", "num_cpus", "phf", "rand 0.8.5", @@ -4765,7 +5395,7 @@ dependencies = [ "rust-s3", "serde", "serde_json", - "serde_with", + "serde_with 3.3.0", "serde_yaml", "sha2 0.10.7", "shellexpand", @@ -4774,8 +5404,8 @@ dependencies = [ "solana-logger", "solana-program", "solana-transaction-status", - "spl-associated-token-account", - "spl-token", + "spl-associated-token-account 1.1.3", + "spl-token 3.5.0", "tabled", "thiserror", "tokio", @@ -5167,7 +5797,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5c266b9ac83dedf0e0385ad78514949e6d89491269e7065bee51d2bb8ec7373" dependencies = [ - "ahash 0.8.3", + "ahash 0.8.4", "gethostname", "log", "serde", @@ -5339,6 +5969,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "unreachable" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" +dependencies = [ + "void", +] + [[package]] name = "untrusted" version = "0.7.1" @@ -5406,6 +6045,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + [[package]] name = "want" version = "0.3.1" @@ -5587,6 +6232,21 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-sys" +version = "0.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -5796,7 +6456,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6580539ad917b7c026220c4b3f2c08d52ce54d6ce0dc491e66002e35388fab46" dependencies = [ "byteorder", - "zerocopy-derive", + "zerocopy-derive 0.2.0", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive 0.7.35", ] [[package]] @@ -5810,6 +6479,17 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2 1.0.67", + "quote 1.0.33", + "syn 2.0.33", +] + [[package]] name = "zeroize" version = "1.3.0" diff --git a/Cargo.toml b/Cargo.toml index 06801022..d2cd9735 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,28 +1,28 @@ [package] -name = "sugar-cli" -version = "2.7.1" -edition = "2021" description = "Command line tool for creating and managing Metaplex Candy Machines." +documentation = "https://developers.metaplex.com/candy-machine/sugar" +edition = "2021" license = "Apache-2.0" +name = "sugar-cli" repository = "https://github.com/metaplex-foundation/sugar" -documentation = "https://developers.metaplex.com/candy-machine/sugar" +version = "2.7.1" [[bin]] name = "sugar" path = "src/main.rs" [dependencies] -anchor-client = "0.27.0" -anchor-lang = "0.27.0" +anchor-client = "0.28.0" +anchor-lang = "0.28.0" anyhow = "1.0.58" async-trait = "0.1.57" borsh = "0.9.3" bs58 = "0.4.0" bundlr-sdk = { version = "0.3.0", default-features = false, features = [ - "solana", + "solana", ] } chrono = { version = "0.4.22", default-features = false, features = ["clock"] } -clap = { version = "3.2.8", features = ["derive", "cargo"] } +clap = { version = "3.2.8", features = ["cargo", "derive"] } console = "0.15.0" ctrlc = "3.2.2" data-encoding = "2.3.2" @@ -35,18 +35,17 @@ hex = "0.4.3" indexmap = { version = "1.9.1", features = ["serde"] } indicatif = { version = "0.16.2", features = ["rayon"] } ini = "1.3.0" -lazy_static = "1.4.0" -mpl-candy-guard = { version = "1.1.0", features = ["no-entrypoint"] } -mpl-candy-machine-core = { version = "1.0.3", features = ["no-entrypoint"] } -mpl-token-metadata = { version = "1.9.0", features = ["no-entrypoint"] } -mpl-token-auth-rules = { version = "~1.3.0", features = ["no-entrypoint"] } +lazy_static = "1.5.0" +mpl-core = "0.8.0-beta.1" +mpl-core-candy-guard = "0.2.1" +mpl-core-candy-machine-core = "0.2.1" num_cpus = "1.13.1" phf = { version = "0.10", features = ["macros"] } rand = "0.8.5" rayon = "1.5.3" regex = "1.5.6" -retry = "1.3.0" reqwest = { version = "0.11.11", features = ["json", "multipart"] } +retry = "1.3.0" ring = "0.16.20" rust-s3 = "0.31.0" serde = { version = "1.0.138", features = ["derive"] } @@ -55,25 +54,25 @@ serde_with = "3.0.0" serde_yaml = "0.8.24" sha2 = "0.10.2" shellexpand = "2.1.0" -solana-account-decoder = "~1.14.14" -solana-client = "~1.14.14" -solana-logger = "~1.14.14" -solana-program = "~1.14.14" -solana-transaction-status = "~1.14.14" +solana-account-decoder = "1.16.27" +solana-client = "1.16.27" +solana-logger = "1.16.27" +solana-program = "1.16.27" +solana-transaction-status = "1.16.27" spl-associated-token-account = "1.1.1" spl-token = "3.3.1" +tabled = "0.12.1" thiserror = "1.0.31" tokio = "1.14.1" tracing = { version = "0.1.35", features = ["log"] } tracing-bunyan-formatter = "0.3.3" tracing-subscriber = { version = "0.3.14", features = [ - "registry", - "env-filter", + "env-filter", + "registry", ] } url = "2.2.2" -tabled = "0.12.1" [dev-dependencies.cargo-husky] -version = "1" default-features = false features = ["precommit-hook", "user-hooks"] +version = "1" diff --git a/src/airdrop/process.rs b/src/airdrop/process.rs index fcb65b4d..357ea517 100644 --- a/src/airdrop/process.rs +++ b/src/airdrop/process.rs @@ -18,7 +18,6 @@ use crate::{ candy_machine::{CANDY_MACHINE_ID, *}, common::*, mint::mint, - pdas::get_metadata_pda, utils::*, }; @@ -34,7 +33,7 @@ pub struct AirdropArgs { pub async fn process_airdrop(args: AirdropArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let mut airdrop_list: AirDropTargets = load_airdrop_list(args.airdrop_list)?; @@ -80,8 +79,7 @@ pub async fn process_airdrop(args: AirdropArgs) -> Result<()> { pb.set_message("Connecting..."); let candy_machine_state = Arc::new(get_candy_machine_state(&sugar_config, &candy_pubkey)?); - let (_, collection_metadata) = - get_metadata_pda(&candy_machine_state.collection_mint, &program)?; + let collection_metadata = get_base_collection(&candy_machine_state.collection_mint, &program)?; let collection_update_authority = collection_metadata.update_authority; pb.finish_with_message("Done"); diff --git a/src/bundlr/process.rs b/src/bundlr/process.rs index 8ceaf03d..45da2b80 100644 --- a/src/bundlr/process.rs +++ b/src/bundlr/process.rs @@ -38,7 +38,7 @@ pub async fn process_bundlr(args: BundlrArgs) -> Result<()> { let pb = spinner_with_style(); pb.set_message("Connecting..."); - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let solana_cluster: Cluster = get_cluster(program.rpc())?; let http_client = reqwest::Client::new(); diff --git a/src/cache.rs b/src/cache.rs index 72862d2d..95cc95b8 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -5,7 +5,7 @@ use std::{ use anchor_client::solana_sdk::pubkey::Pubkey; use anyhow::Result; -use mpl_candy_machine_core::ConfigLine; +use mpl_core_candy_machine_core::ConfigLine; use serde::{Deserialize, Serialize}; use crate::{common::*, pdas::find_candy_machine_creator_pda}; diff --git a/src/candy_machine.rs b/src/candy_machine.rs index 3b30ff76..836d953c 100644 --- a/src/candy_machine.rs +++ b/src/candy_machine.rs @@ -1,10 +1,10 @@ use anchor_client::{solana_sdk::pubkey::Pubkey, ClientError}; use anchor_lang::AnchorDeserialize; use anyhow::{anyhow, Result}; -pub use mpl_candy_machine_core::ID as CANDY_MACHINE_ID; -use mpl_candy_machine_core::{CandyMachine, CandyMachineData}; +pub use mpl_core_candy_machine_core::ID as CANDY_MACHINE_ID; +use mpl_core_candy_machine_core::{CandyMachine, CandyMachineData}; -use crate::{config::data::SugarConfig, pdas::get_metadata_pda, setup::setup_client}; +use crate::{config::data::SugarConfig, setup::setup_client}; // To test a custom candy machine program, comment the mpl_candy_machine::ID line // above and use the following lines to declare the id to use: @@ -24,7 +24,7 @@ pub fn get_candy_machine_state( candy_machine_id: &Pubkey, ) -> Result { let client = setup_client(sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; program.account(*candy_machine_id).map_err(|e| match e { ClientError::AccountNotFound => anyhow!("Candy Machine does not exist!"), @@ -47,16 +47,10 @@ pub fn get_candy_machine_data( pub fn load_candy_machine( sugar_config: &SugarConfig, candy_machine_id: &Pubkey, -) -> Result<(CandyMachine, Option)> { +) -> Result { let client = setup_client(sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; // retrieves the account data let data = program.rpc().get_account_data(candy_machine_id)?; - let candy_machine = CandyMachine::deserialize(&mut &data[8..])?; - - let (_, collection_metadata) = get_metadata_pda(&candy_machine.collection_mint, &program)?; - - let rule_set = candy_machine.get_rule_set(&data, &collection_metadata)?; - - Ok((candy_machine, rule_set)) + Ok(CandyMachine::deserialize(&mut &data[8..])?) } diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 3e404794..4e909f14 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -1,11 +1,8 @@ use clap::{Parser, Subcommand}; -use crate::{ - config::TokenStandard, - constants::{ - DEFAULT_AIRDROP_LIST, DEFAULT_AIRDROP_LIST_HELP, DEFAULT_ASSETS, DEFAULT_CACHE, - DEFAULT_CONFIG, DEFAULT_PRIORITY_FEE, - }, +use crate::constants::{ + DEFAULT_AIRDROP_LIST, DEFAULT_AIRDROP_LIST_HELP, DEFAULT_ASSETS, DEFAULT_CACHE, DEFAULT_CONFIG, + DEFAULT_PRIORITY_FEE, }; #[derive(Parser)] @@ -238,29 +235,6 @@ pub enum Commands { unminted: bool, }, - /// Sign one or all NFTs from candy machine - Sign { - /// Path to the keypair file, uses Sol config or defaults to "~/.config/solana/id.json" - #[clap(short, long)] - keypair: Option, - - /// RPC Url - #[clap(short, long)] - rpc_url: Option, - - /// Path to the cache file, defaults to "cache.json" - #[clap(long, default_value = DEFAULT_CACHE)] - cache: String, - - /// Mint id for single NFT to be signed - #[clap(short, long)] - mint: Option, - - /// Candy machine id. - #[clap(long)] - candy_machine_id: Option, - }, - /// Upload assets to storage and creates the cache config Upload { /// Path to the directory with the assets to upload @@ -406,36 +380,6 @@ pub enum ConfigSubcommands { #[clap(long)] candy_machine: Option, }, - /// Set specific candy machine config values - Set { - /// Path to the keypair file, uses Sol config or defaults to "~/.config/solana/id.json" - #[clap(short, long)] - keypair: Option, - - /// RPC Url - #[clap(short, long)] - rpc_url: Option, - - /// Path to the cache file, defaults to "cache.json" - #[clap(long, default_value = DEFAULT_CACHE)] - cache: String, - - /// Priority fee value - #[clap(short, long, default_value_t = DEFAULT_PRIORITY_FEE)] - priority_fee: u64, - - /// Token Standard to set. - #[clap(short, long)] - token_standard: Option, - - /// Address of candy machine to update. - #[clap(long)] - candy_machine: Option, - - /// Address of the rule set to use. - #[clap(long)] - rule_set: Option, - }, } #[derive(Subcommand)] diff --git a/src/collections/set.rs b/src/collections/set.rs index b0fd3ba9..de976d12 100644 --- a/src/collections/set.rs +++ b/src/collections/set.rs @@ -5,15 +5,8 @@ use anchor_client::solana_sdk::{ }; use anyhow::Result; use console::style; -use mpl_candy_machine_core::{ - accounts as nft_accounts, instruction as nft_instruction, AccountVersion, -}; -use mpl_token_metadata::{ - error::MetadataError, - instruction::MetadataDelegateRole, - pda::{find_collection_authority_account, find_metadata_delegate_record_account}, - state::{MasterEditionV2, Metadata}, -}; +use mpl_core::accounts::BaseCollectionV1; +use mpl_core_candy_machine_core::{accounts as nft_accounts, instruction as nft_instruction}; use crate::{ cache::load_cache, @@ -23,7 +16,7 @@ use crate::{ hash::hash_and_update, pdas::*, update::{process_update, UpdateArgs}, - utils::{assert_correct_authority, spinner_with_style}, + utils::{assert_correct_authority, get_base_collection, spinner_with_style}, }; pub struct SetCollectionArgs { @@ -39,7 +32,7 @@ pub struct SetCollectionArgs { pub fn process_set_collection(args: SetCollectionArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair.clone(), args.rpc_url.clone())?; let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let mut cache = Cache::new(); // The candy machine id specified takes precedence over the one from the cache. @@ -85,9 +78,7 @@ pub fn process_set_collection(args: SetCollectionArgs) -> Result<()> { let candy_machine_state = get_candy_machine_state(&sugar_config, &Pubkey::from_str(&candy_machine_id)?)?; - let collection_metadata_info = get_metadata_pda(&collection_mint_pubkey, &program)?; - - let collection_edition_info = get_master_edition_pda(&collection_mint_pubkey, &program)?; + let collection_info = get_base_collection(&collection_mint_pubkey, &program)?; pb.finish_with_message("Done"); @@ -110,8 +101,7 @@ pub fn process_set_collection(args: SetCollectionArgs) -> Result<()> { &candy_pubkey, &candy_machine_state, &collection_mint_pubkey, - &collection_metadata_info, - &collection_edition_info, + &collection_info, &args, )?; @@ -165,36 +155,20 @@ pub fn set_collection + Clone>( candy_pubkey: &Pubkey, candy_machine_state: &CandyMachine, new_collection_mint_pubkey: &Pubkey, - new_collection_metadata_info: &PdaInfo, - new_collection_edition_info: &PdaInfo, + new_collection: &BaseCollectionV1, args: &SetCollectionArgs, ) -> Result { let payer = program.payer(); - let (authority_pda, _) = find_candy_machine_creator_pda(candy_pubkey); - - let (new_collection_metadata_pubkey, new_collection_metadata) = new_collection_metadata_info; - let (new_collection_edition_pubkey, new_collection_edition) = new_collection_edition_info; + // let (authority_pda, _) = find_candy_machine_creator_pda(candy_pubkey); - let new_collection_delegate_record = find_metadata_delegate_record_account( - new_collection_mint_pubkey, - MetadataDelegateRole::Collection, - &new_collection_metadata.update_authority, - &authority_pda, - ) - .0; - - if new_collection_metadata.update_authority != payer { + if new_collection.update_authority != payer { return Err(anyhow!(CustomCandyError::AuthorityMismatch( - new_collection_metadata.update_authority.to_string(), + new_collection.update_authority.to_string(), payer.to_string() ))); } - if new_collection_edition.max_supply != Some(0) { - return Err(anyhow!(MetadataError::CollectionMustBeAUniqueMasterEdition)); - } - if candy_machine_state.items_redeemed > 0 { return Err(anyhow!( "You can't modify the Candy Machine collection after items have been minted." @@ -202,50 +176,31 @@ pub fn set_collection + Clone>( } let collection_mint = candy_machine_state.collection_mint; - let (_, collection_metadata) = get_metadata_pda(&candy_machine_state.collection_mint, program)?; + let collection = get_base_collection(&candy_machine_state.collection_mint, program)?; let (authority_pda, _) = find_candy_machine_creator_pda(candy_pubkey); - let collection_delegate_record = if matches!(candy_machine_state.version, AccountVersion::V1) { - find_collection_authority_account(&collection_mint, &authority_pda).0 - } else { - find_metadata_delegate_record_account( - &collection_mint, - MetadataDelegateRole::Collection, - &collection_metadata.update_authority, - &authority_pda, - ) - .0 - }; - let collection_update_authority = collection_metadata.update_authority; - let collection_metadata = find_metadata_pda(&collection_mint); + let collection_update_authority = collection.update_authority; let priority_fee = ComputeBudgetInstruction::set_compute_unit_price(args.priority_fee); let builder = program .request() .instruction(priority_fee) - .accounts(nft_accounts::SetCollectionV2 { + .accounts(nft_accounts::SetCollection { candy_machine: *candy_pubkey, authority: payer, authority_pda, payer, - collection_mint, - collection_metadata, collection_update_authority, - collection_delegate_record, - new_collection_metadata: *new_collection_metadata_pubkey, - new_collection_mint: *new_collection_mint_pubkey, - new_collection_master_edition: *new_collection_edition_pubkey, - new_collection_delegate_record, - new_collection_update_authority: new_collection_metadata.update_authority, - token_metadata_program: mpl_token_metadata::ID, - system_program: system_program::id(), + collection: collection_mint, + new_collection_update_authority: new_collection.update_authority, + new_collection: *new_collection_mint_pubkey, + mpl_core_program: mpl_core::ID, + system_program: system_program::ID, sysvar_instructions: sysvar::instructions::ID, - authorization_rules_program: None, - authorization_rules: None, }) - .args(nft_instruction::SetCollectionV2); + .args(nft_instruction::SetCollection); let sig = builder.send()?; diff --git a/src/common.rs b/src/common.rs index 38b65d7e..627b2bfb 100644 --- a/src/common.rs +++ b/src/common.rs @@ -19,7 +19,7 @@ pub use anchor_lang::AccountDeserialize; pub use anyhow::{anyhow, Result}; pub use bs58; pub use indexmap::IndexMap; -pub use mpl_candy_machine_core::{ +pub use mpl_core_candy_machine_core::{ accounts as nft_accounts, instruction as nft_instruction, CandyMachine, }; pub use reqwest::{Client as HttpClient, Response}; @@ -32,5 +32,5 @@ pub use crate::{ constants::*, errors::*, parse::path_to_string, - setup::{setup_client, sugar_setup}, + setup::{setup_async_client, setup_client, sugar_setup}, }; diff --git a/src/config/data.rs b/src/config/data.rs index 337f7ca8..bea15f54 100644 --- a/src/config/data.rs +++ b/src/config/data.rs @@ -28,16 +28,9 @@ pub struct SolanaConfig { #[derive(Serialize, Deserialize, Debug, Clone, Default)] #[serde(rename_all = "camelCase")] pub struct ConfigData { - /// Token standard. - #[serde(default)] - pub token_standard: TokenStandard, - /// Number of assets available pub number: u64, - /// Symbol for the asset - pub symbol: String, - /// Secondary sales royalty basis points (0-10000) pub seller_fee_basis_points: u16, @@ -48,7 +41,7 @@ pub struct ConfigData { pub is_sequential: bool, /// List of creators - pub creators: Vec, + // pub creators: Vec, /// Upload method to use pub upload_method: UploadMethod, @@ -184,13 +177,13 @@ pub fn price_as_lamports(price: f64) -> u64 { (price * LAMPORTS_PER_SOL as f64) as u64 } -fn to_pubkey<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let s: String = Deserialize::deserialize(deserializer)?; - Pubkey::from_str(&s).map_err(serde::de::Error::custom) -} +// fn to_pubkey<'de, D>(deserializer: D) -> Result +// where +// D: Deserializer<'de>, +// { +// let s: String = Deserialize::deserialize(deserializer)?; +// Pubkey::from_str(&s).map_err(serde::de::Error::custom) +// } #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct HiddenSettings { @@ -203,8 +196,8 @@ impl HiddenSettings { pub fn new(name: String, uri: String, hash: String) -> HiddenSettings { HiddenSettings { name, uri, hash } } - pub fn to_candy_format(&self) -> mpl_candy_machine_core::HiddenSettings { - mpl_candy_machine_core::HiddenSettings { + pub fn to_candy_format(&self) -> mpl_core_candy_machine_core::HiddenSettings { + mpl_core_candy_machine_core::HiddenSettings { name: self.name.clone(), uri: self.uri.clone(), hash: self.hash.as_bytes().try_into().unwrap_or([0; 32]), @@ -236,25 +229,25 @@ impl Display for UploadMethod { } } -#[derive(Debug, Clone, Deserialize, Default, Serialize)] -pub struct Creator { - #[serde(deserialize_with = "to_pubkey")] - #[serde(serialize_with = "to_string")] - pub address: Pubkey, - pub share: u8, -} - -impl Creator { - pub fn to_candy_format(&self) -> Result { - let creator = mpl_candy_machine_core::Creator { - address: self.address, - percentage_share: self.share, - verified: false, - }; - - Ok(creator) - } -} +// #[derive(Debug, Clone, Deserialize, Default, Serialize)] +// pub struct Creator { +// #[serde(deserialize_with = "to_pubkey")] +// #[serde(serialize_with = "to_string")] +// pub address: Pubkey, +// pub share: u8, +// } + +// impl Creator { +// pub fn to_candy_format(&self) -> Result { +// let creator = mpl_core_candy_machine_core::Creator { +// address: self.address, +// percentage_share: self.share, +// verified: false, +// }; + +// Ok(creator) +// } +// } #[derive(Debug, Clone, Serialize)] pub enum Cluster { @@ -278,6 +271,7 @@ impl FromStr for Cluster { } } +#[allow(clippy::to_string_trait_impl)] impl ToString for Cluster { fn to_string(&self) -> String { match self { @@ -288,42 +282,3 @@ impl ToString for Cluster { } } } - -#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)] -#[serde(rename_all = "snake_case")] -pub enum TokenStandard { - #[serde(rename = "nft")] - #[default] - NonFungible, - #[serde(rename = "pnft")] - ProgrammableNonFungible, -} - -impl Display for TokenStandard { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -impl From for mpl_token_metadata::state::TokenStandard { - fn from(token_standard: TokenStandard) -> Self { - match token_standard { - TokenStandard::NonFungible => mpl_token_metadata::state::TokenStandard::NonFungible, - TokenStandard::ProgrammableNonFungible => { - mpl_token_metadata::state::TokenStandard::ProgrammableNonFungible - } - } - } -} - -impl FromStr for TokenStandard { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - match s { - "nft" => Ok(TokenStandard::NonFungible), - "pnft" => Ok(TokenStandard::ProgrammableNonFungible), - _ => Err(ConfigError::InvalidTokenStandard(s.to_string()).into()), - } - } -} diff --git a/src/config/guard_data.rs b/src/config/guard_data.rs index b0bd3802..726e1493 100644 --- a/src/config/guard_data.rs +++ b/src/config/guard_data.rs @@ -13,7 +13,7 @@ pub struct CandyGuardData { } impl CandyGuardData { - pub fn to_guard_format(&self) -> Result { + pub fn to_guard_format(&self) -> Result { let groups = if let Some(groups) = &self.groups { let mut group_vec = Vec::with_capacity(groups.len()); @@ -26,7 +26,7 @@ impl CandyGuardData { None }; - Ok(mpl_candy_guard::state::CandyGuardData { + Ok(mpl_core_candy_guard::state::CandyGuardData { default: self.default.to_guard_format()?, groups, }) @@ -40,8 +40,8 @@ pub struct Group { } impl Group { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::state::Group { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::state::Group { label: self.label.clone(), guards: self.guards.to_guard_format()?, }) @@ -94,10 +94,16 @@ pub struct GuardSet { pub allocation: Option, /// Token2022 payment guard (set the price for the mint in spl-token-2022 amount). pub token2022_payment: Option, + /// Sol fixed fee for launchpads, marketplaces to define custom fees + pub sol_fixed_fee: Option, + /// NFT mint limit guard (add a limit on the number of mints per NFT). + pub nft_mint_limit: Option, + /// NFT mint limit guard (add a limit on the number of mints per NFT). + pub edition: Option, } impl GuardSet { - pub fn to_guard_format(&self) -> Result { + pub fn to_guard_format(&self) -> Result { // bot tax let bot_tax = if let Some(bot_tax) = &self.bot_tax { Some(bot_tax.to_guard_format()?) @@ -225,7 +231,28 @@ impl GuardSet { None }; - Ok(mpl_candy_guard::guards::GuardSet { + // sol fixed fee + let sol_fixed_fee = if let Some(sol_fixed_fee) = &self.sol_fixed_fee { + Some(sol_fixed_fee.to_guard_format()?) + } else { + None + }; + + // nft mint limit + let nft_mint_limit = if let Some(nft_mint_limit) = &self.nft_mint_limit { + Some(nft_mint_limit.to_guard_format()?) + } else { + None + }; + + // edition + let edition = if let Some(edition) = &self.edition { + Some(edition.to_guard_format()?) + } else { + None + }; + + Ok(mpl_core_candy_guard::guards::GuardSet { bot_tax, sol_payment, token_payment, @@ -247,6 +274,9 @@ impl GuardSet { program_gate, allocation, token2022_payment, + sol_fixed_fee, + nft_mint_limit, + edition, }) } } @@ -261,14 +291,14 @@ pub struct AddressGate { } impl AddressGate { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::AddressGate { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::AddressGate { address: self.address, }) } } -// Alow List guard +// Allow List guard #[derive(Serialize, Deserialize, Debug, Clone, Default)] #[serde(rename_all = "camelCase")] @@ -277,11 +307,11 @@ pub struct AllowList { } impl AllowList { - pub fn to_guard_format(&self) -> Result { + pub fn to_guard_format(&self) -> Result { let root: [u8; 32] = hex::decode(&self.merkle_root)? .try_into() .map_err(|_| anyhow!("Invalid merkle root value: {}", self.merkle_root))?; - Ok(mpl_candy_guard::guards::AllowList { merkle_root: root }) + Ok(mpl_core_candy_guard::guards::AllowList { merkle_root: root }) } } @@ -296,14 +326,29 @@ pub struct BotTax { } impl BotTax { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::BotTax { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::BotTax { lamports: price_as_lamports(self.value), last_instruction: self.last_instruction, }) } } +// Edition guard + +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct Edition { + pub edition_start_offset: u32, +} + +impl Edition { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::Edition { + edition_start_offset: self.edition_start_offset, + }) + } +} + // End Date guard #[derive(Serialize, Deserialize, Debug, Clone, Default)] @@ -312,10 +357,10 @@ pub struct EndDate { } impl EndDate { - pub fn to_guard_format(&self) -> Result { + pub fn to_guard_format(&self) -> Result { let timestamp = self.date.parse::()?.0.timestamp(); - Ok(mpl_candy_guard::guards::EndDate { date: timestamp }) + Ok(mpl_core_candy_guard::guards::EndDate { date: timestamp }) } } @@ -332,8 +377,8 @@ pub struct Gatekeeper { } impl Gatekeeper { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::Gatekeeper { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::Gatekeeper { gatekeeper_network: self.gatekeeper_network, expire_on_use: self.expire_on_use, }) @@ -350,8 +395,8 @@ pub struct MintLimit { } impl MintLimit { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::MintLimit { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::MintLimit { id: self.id, limit: self.limit, }) @@ -369,8 +414,8 @@ pub struct NftBurn { } impl NftBurn { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::NftBurn { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::NftBurn { required_collection: self.required_collection, }) } @@ -387,8 +432,27 @@ pub struct NftGate { } impl NftGate { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::NftGate { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::NftGate { + required_collection: self.required_collection, + }) + } +} + +// Nft Mint Limit guard + +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct NftMintLimit { + pub id: u8, + pub limit: u16, + pub required_collection: Pubkey, +} + +impl NftMintLimit { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::NftMintLimit { + id: self.id, + limit: self.limit, required_collection: self.required_collection, }) } @@ -409,8 +473,8 @@ pub struct NftPayment { } impl NftPayment { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::NftPayment { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::NftPayment { required_collection: self.required_collection, destination: self.destination, }) @@ -425,13 +489,30 @@ pub struct RedeemedAmount { } impl RedeemedAmount { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::RedeemedAmount { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::RedeemedAmount { maximum: self.maximum, }) } } +// Sol Fixed Fee guard + +#[derive(Serialize, Deserialize, Debug, Clone, Default)] +pub struct SolFixedFee { + pub value: f64, + pub destination: Pubkey, +} + +impl SolFixedFee { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::SolFixedFee { + lamports: price_as_lamports(self.value), + destination: self.destination, + }) + } +} + // Sol Payment guard #[derive(Serialize, Deserialize, Debug, Clone, Default)] @@ -444,8 +525,8 @@ pub struct SolPayment { } impl SolPayment { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::SolPayment { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::SolPayment { lamports: price_as_lamports(self.value), destination: self.destination, }) @@ -458,9 +539,9 @@ pub struct StartDate { } impl StartDate { - pub fn to_guard_format(&self) -> Result { + pub fn to_guard_format(&self) -> Result { let timestamp = self.date.parse::()?.0.timestamp(); - Ok(mpl_candy_guard::guards::StartDate { date: timestamp }) + Ok(mpl_core_candy_guard::guards::StartDate { date: timestamp }) } } @@ -475,8 +556,8 @@ pub struct ThirdPartySigner { } impl ThirdPartySigner { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::ThirdPartySigner { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::ThirdPartySigner { signer_key: self.signer_key, }) } @@ -494,8 +575,8 @@ pub struct TokenBurn { } impl TokenBurn { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::TokenBurn { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::TokenBurn { amount: self.amount, mint: self.mint, }) @@ -514,8 +595,8 @@ pub struct TokenGate { } impl TokenGate { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::TokenGate { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::TokenGate { amount: self.amount, mint: self.mint, }) @@ -539,8 +620,8 @@ pub struct TokenPayment { } impl TokenPayment { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::TokenPayment { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::TokenPayment { amount: self.amount, mint: self.mint, destination_ata: self.destination_ata, @@ -561,8 +642,8 @@ pub struct FreezeSolPayment { } impl FreezeSolPayment { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::FreezeSolPayment { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::FreezeSolPayment { lamports: price_as_lamports(self.value), destination: self.destination, }) @@ -586,8 +667,8 @@ pub struct FreezeTokenPayment { } impl FreezeTokenPayment { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::FreezeTokenPayment { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::FreezeTokenPayment { amount: self.amount, mint: self.mint, destination_ata: self.destination_ata, @@ -606,8 +687,8 @@ pub struct ProgramGate { } impl ProgramGate { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::ProgramGate { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::ProgramGate { additional: self.additional.clone(), }) } @@ -623,8 +704,8 @@ pub struct Allocation { } impl Allocation { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::Allocation { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::Allocation { id: self.id, limit: self.limit, }) @@ -648,8 +729,8 @@ pub struct Token2022Payment { } impl Token2022Payment { - pub fn to_guard_format(&self) -> Result { - Ok(mpl_candy_guard::guards::Token2022Payment { + pub fn to_guard_format(&self) -> Result { + Ok(mpl_core_candy_guard::guards::Token2022Payment { amount: self.amount, mint: self.mint, destination_ata: self.destination_ata, diff --git a/src/constants.rs b/src/constants.rs index 09e928c1..da1a7be2 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,7 +1,4 @@ use console::Emoji; -pub use mpl_token_metadata::state::{ - MAX_CREATOR_LEN, MAX_CREATOR_LIMIT, MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH, -}; /// Metaplex program id. pub const METAPLEX_PROGRAM_ID: &str = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"; @@ -12,8 +9,6 @@ pub const CONFIG_CHUNK_SIZE: usize = 10; pub const CONFIG_NAME_OFFSET: usize = STRING_LEN_SIZE; -pub const CONFIG_URI_OFFSET: usize = STRING_LEN_SIZE + CONFIG_NAME_OFFSET + MAX_NAME_LENGTH; - pub const MINT_LAYOUT: u64 = 82; pub const VALID_CATEGORIES: [&str; 5] = ["image", "video", "audio", "vr", "html"]; diff --git a/src/create_config/process.rs b/src/create_config/process.rs index 1628ef8b..ef6a8535 100644 --- a/src/create_config/process.rs +++ b/src/create_config/process.rs @@ -12,7 +12,7 @@ use dialoguer::{Confirm, Input, MultiSelect, Select}; use url::Url; use crate::{ - config::{AwsConfig, ConfigData, Creator, HiddenSettings, PinataConfig, UploadMethod}, + config::{AwsConfig, ConfigData, HiddenSettings, PinataConfig, UploadMethod}, constants::*, upload::list_files, utils::get_dialoguer_theme, @@ -24,7 +24,7 @@ const DEFAULT_METADATA: &str = "0.json"; /// Default value to represent an invalid seller fee basis points. const INVALID_SELLER_FEE: u16 = u16::MAX; -const INVALID_SYMBOL: &str = "abcdefghijklmnopqrstuvwxyz"; +// const INVALID_SYMBOL: &str = "abcdefghijklmnopqrstuvwxyz"; pub struct CreateConfigArgs { pub keypair: Option, @@ -66,14 +66,6 @@ pub fn process_create_config(args: CreateConfigArgs) -> Result<()> { } }; - let symbol_validator = |input: &String| -> Result<(), String> { - if input.len() > 10 { - Err(String::from("Symbol must be 10 characters or less.")) - } else { - Ok(()) - } - }; - let seller_fee_basis_points_validator = |input: &String| -> Result<(), String> { let value = match input.parse::() { Ok(value) => value, @@ -101,7 +93,7 @@ pub fn process_create_config(args: CreateConfigArgs) -> Result<()> { _ => 0, }; - let mut symbol: String = INVALID_SYMBOL.to_string(); + // let mut symbol: String = INVALID_SYMBOL.to_string(); let mut seller_fee = INVALID_SELLER_FEE; if num_files > 0 { @@ -120,11 +112,6 @@ pub fn process_create_config(args: CreateConfigArgs) -> Result<()> { anyhow!("Failed to read metadata file '{metadata_file}' with error: {e}") })?; - // Optional in the JSON, so if it doesn't exist, we'll use the default value. - if let Some(s) = metadata.symbol { - symbol = s; - } - // Optional in the JSON, so if it doesn't exist, we'll use the default value. if let Some(sfbp) = metadata.seller_fee_basis_points { seller_fee = sfbp; @@ -158,31 +145,6 @@ pub fn process_create_config(args: CreateConfigArgs) -> Result<()> { .unwrap().parse::().expect("Failed to parse number into u64 that should have already been validated.") }; - // symbol - - config_data.symbol = if num_files > 0 - && symbol != *INVALID_SYMBOL - && Confirm::with_theme(&theme) - .with_prompt(format!( - "Found {} in your metadata file. Is this value correct?", - if symbol.is_empty() { - "no symbol".to_string() - } else { - format!("symbol \"{}\"", symbol) - }, - )) - .interact()? - { - symbol - } else { - Input::with_theme(&theme) - .with_prompt("What is the symbol of your collection? Hit [ENTER] for no symbol.") - .allow_empty(true) - .validate_with(symbol_validator) - .interact() - .unwrap() - }; - // seller_fee_basis_points config_data.seller_fee_basis_points = if num_files > 0 && seller_fee != INVALID_SELLER_FEE && Confirm::with_theme(&theme) @@ -215,58 +177,58 @@ pub fn process_create_config(args: CreateConfigArgs) -> Result<()> { // creators - let num_creators = Input::with_theme(&theme) - .with_prompt("How many creator wallets do you have? (max limit of 4)") - .validate_with(number_validator) - .validate_with({ - |input: &String| match input.parse::().unwrap() { - 1..=4 => Ok(()), - _ => Err("Number of creator wallets must be between 1 and 4, inclusive."), - } - }) - .interact() - .unwrap() - .parse::() - .expect("Failed to parse number into u8 that should have already been validated."); - - let mut total_share = 0; - - (0..num_creators).for_each(|i| { - let address = Pubkey::from_str( - &Input::with_theme(&theme) - .with_prompt(format!("Enter creator wallet address #{}", i + 1)) - .validate_with(pubkey_validator) - .interact() - .unwrap(), - ) - .expect("Failed to parse string into pubkey that should have already been validated."); - - let share = Input::with_theme(&theme) - .with_prompt(format!( - "Enter royalty percentage share for creator #{} (e.g., 70). Total shares must add to 100.", - i + 1 - )) - .validate_with(number_validator) - .validate_with({ - |input: &String| -> Result<(), &str> { - if input.parse::().unwrap() + total_share > 100 { - Err("Royalty share total has exceeded 100 percent.") - } else if i == num_creators && input.parse::().unwrap() + total_share != 100 { - Err("Royalty share for all creators must total 100 percent.") - } else { - Ok(()) - } - } - }) - .interact() - .unwrap() - .parse::() - .expect("Failed to parse number into u64 that should have already been validated."); - - total_share += share; - let creator = Creator { address, share }; - config_data.creators.push(creator); - }); + // let num_creators = Input::with_theme(&theme) + // .with_prompt("How many creator wallets do you have? (max limit of 4)") + // .validate_with(number_validator) + // .validate_with({ + // |input: &String| match input.parse::().unwrap() { + // 1..=4 => Ok(()), + // _ => Err("Number of creator wallets must be between 1 and 4, inclusive."), + // } + // }) + // .interact() + // .unwrap() + // .parse::() + // .expect("Failed to parse number into u8 that should have already been validated."); + + // let mut total_share = 0; + + // (0..num_creators).for_each(|i| { + // let address = Pubkey::from_str( + // &Input::with_theme(&theme) + // .with_prompt(format!("Enter creator wallet address #{}", i + 1)) + // .validate_with(pubkey_validator) + // .interact() + // .unwrap(), + // ) + // .expect("Failed to parse string into pubkey that should have already been validated."); + + // let share = Input::with_theme(&theme) + // .with_prompt(format!( + // "Enter royalty percentage share for creator #{} (e.g., 70). Total shares must add to 100.", + // i + 1 + // )) + // .validate_with(number_validator) + // .validate_with({ + // |input: &String| -> Result<(), &str> { + // if input.parse::().unwrap() + total_share > 100 { + // Err("Royalty share total has exceeded 100 percent.") + // } else if i == num_creators && input.parse::().unwrap() + total_share != 100 { + // Err("Royalty share for all creators must total 100 percent.") + // } else { + // Ok(()) + // } + // } + // }) + // .interact() + // .unwrap() + // .parse::() + // .expect("Failed to parse number into u64 that should have already been validated."); + + // total_share += share; + // let creator = Creator { address, share }; + // config_data.creators.push(creator); + // }); const HIDDEN_SETTINGS_INDEX: usize = 0; @@ -282,24 +244,10 @@ pub fn process_create_config(args: CreateConfigArgs) -> Result<()> { config_data.hidden_settings = if choices.contains(&HIDDEN_SETTINGS_INDEX) { let name = Input::with_theme(&theme) .with_prompt("What is the prefix name for your hidden settings mints? The mint index will be appended at the end of the name.") - .validate_with(|name: &String| { - if name.len() > (MAX_NAME_LENGTH - 7) { - Err("Your hidden settings name probably cannot be longer than 25 characters.") - } else { - Ok(()) - } - }) .interact() .unwrap(); let uri = Input::with_theme(&theme) .with_prompt("What is URI to be used for each mint?") - .validate_with(|uri: &String| { - if uri.len() > MAX_URI_LENGTH { - Err("The URI cannot be longer than 200 characters.") - } else { - Ok(()) - } - }) .validate_with(url_validator) .interact() .unwrap(); diff --git a/src/deploy/collection.rs b/src/deploy/collection.rs index 890378f8..384b6057 100644 --- a/src/deploy/collection.rs +++ b/src/deploy/collection.rs @@ -1,23 +1,9 @@ use anchor_client::solana_sdk::{compute_budget::ComputeBudgetInstruction, pubkey::Pubkey}; use anyhow::Result; -use mpl_token_metadata::{ - instruction::{create_master_edition_v3, create_metadata_accounts_v3}, - state::{CollectionDetails, Creator}, -}; -use spl_associated_token_account::{ - get_associated_token_address, instruction::create_associated_token_account, -}; -use spl_token::{ - instruction::{initialize_mint, mint_to}, - ID as TOKEN_PROGRAM_ID, -}; +use mpl_core::instructions::{CreateCollectionV1, CreateCollectionV1InstructionArgs}; use crate::{ - candy_machine::CANDY_MACHINE_ID, - common::*, - config::ConfigData, - deploy::DeployArgs, - pdas::{find_master_edition_pda, find_metadata_pda}, + candy_machine::CANDY_MACHINE_ID, common::*, config::ConfigData, deploy::DeployArgs, setup::SugarClient, }; @@ -25,10 +11,10 @@ pub fn create_collection( client: &SugarClient, _candy_machine: Pubkey, cache: &mut Cache, - config_data: &ConfigData, + _config_data: &ConfigData, args: &DeployArgs, ) -> Result<(Signature, Pubkey)> { - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let payer = program.payer(); let collection_mint = Keypair::new(); @@ -39,95 +25,25 @@ pub fn create_collection( } }; - // Allocate memory for the account - let min_rent = program - .rpc() - .get_minimum_balance_for_rent_exemption(MINT_LAYOUT as usize)?; - - // Create mint account - let create_mint_account_ix = system_instruction::create_account( - &payer, - &collection_mint.pubkey(), - min_rent, - MINT_LAYOUT, - &TOKEN_PROGRAM_ID, - ); - - // Initialize mint ix - let init_mint_ix = initialize_mint( - &TOKEN_PROGRAM_ID, - &collection_mint.pubkey(), - &payer, - Some(&payer), - 0, - )?; - - let ata_pubkey = get_associated_token_address(&payer, &collection_mint.pubkey()); - - // Create associated account instruction - let create_assoc_account_ix = - create_associated_token_account(&payer, &payer, &collection_mint.pubkey(), &spl_token::ID); - - // Mint to instruction - let mint_to_ix = mint_to( - &TOKEN_PROGRAM_ID, - &collection_mint.pubkey(), - &ata_pubkey, - &payer, - &[], - 1, - )?; - - let creator = Creator { - address: payer, - verified: true, - share: 100, - }; - let collection_metadata_pubkey = find_metadata_pda(&collection_mint.pubkey()); - - let create_metadata_account_ix = create_metadata_accounts_v3( - mpl_token_metadata::ID, - collection_metadata_pubkey, - collection_mint.pubkey(), - payer, - payer, + let create_metadata_account_ix = CreateCollectionV1 { + collection: collection_mint.pubkey(), + update_authority: None, payer, - collection_item.name.clone(), - config_data.symbol.clone(), - collection_item.metadata_link.clone(), - Some(vec![creator]), - 0, - true, - true, - None, - None, - Some(CollectionDetails::V1 { size: 0 }), - ); + system_program: system_program::ID, + } + .instruction(CreateCollectionV1InstructionArgs { + name: collection_item.name.clone(), + uri: collection_item.metadata_link.clone(), + plugins: None, + }); - let collection_edition_pubkey = find_master_edition_pda(&collection_mint.pubkey()); - - let create_master_edition_ix = create_master_edition_v3( - mpl_token_metadata::ID, - collection_edition_pubkey, - collection_mint.pubkey(), - payer, - payer, - collection_metadata_pubkey, - payer, - Some(0), - ); let priority_fee = ComputeBudgetInstruction::set_compute_unit_price(args.priority_fee); let builder = program .request() .instruction(priority_fee) - .instruction(create_mint_account_ix) - .instruction(init_mint_ix) - .instruction(create_assoc_account_ix) - .instruction(mint_to_ix) .signer(&collection_mint) - .instruction(create_metadata_account_ix) - .instruction(create_master_edition_ix); + .instruction(create_metadata_account_ix); let sig = builder.send()?; diff --git a/src/deploy/config_lines.rs b/src/deploy/config_lines.rs index 63fa8755..3426c25b 100644 --- a/src/deploy/config_lines.rs +++ b/src/deploy/config_lines.rs @@ -12,12 +12,9 @@ use anchor_client::solana_sdk::{ use anyhow::Result; use console::style; use futures::future::select_all; -use mpl_candy_machine_core::{ +use mpl_core_candy_machine_core::{ accounts as nft_accounts, instruction as nft_instruction, CandyMachineData, ConfigLine, }; -pub use mpl_token_metadata::state::{ - MAX_CREATOR_LIMIT, MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH, -}; use crate::{ cache::*, candy_machine::CANDY_MACHINE_ID, common::*, config::data::*, deploy::errors::*, @@ -223,7 +220,7 @@ pub async fn add_config_lines( priority_fee: u64, ) -> Result> { let client = setup_client(&config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; // this will be used to update the cache let mut indices: Vec = Vec::new(); diff --git a/src/deploy/initialize.rs b/src/deploy/initialize.rs index 51af0a26..a6d22961 100644 --- a/src/deploy/initialize.rs +++ b/src/deploy/initialize.rs @@ -7,24 +7,13 @@ use anchor_client::solana_sdk::{ system_instruction, system_program, }; use anyhow::Result; -use mpl_candy_machine_core::{ +use mpl_core_candy_machine_core::{ accounts as nft_accounts, instruction as nft_instruction, CandyMachineData, ConfigLineSettings, - Creator as CandyCreator, -}; -pub use mpl_token_metadata::state::{ - MAX_CREATOR_LIMIT, MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH, -}; -use mpl_token_metadata::{ - instruction::MetadataDelegateRole, pda::find_metadata_delegate_record_account, - state::TokenStandard, }; use solana_program::native_token::LAMPORTS_PER_SOL; use crate::{ - common::*, - config::data::*, - deploy::errors::*, - pdas::{find_candy_machine_creator_pda, find_master_edition_pda, find_metadata_pda}, + common::*, config::data::*, deploy::errors::*, pdas::find_candy_machine_creator_pda, setup::SugarClient, }; @@ -34,29 +23,26 @@ pub fn create_candy_machine_data( config: &ConfigData, cache: &Cache, ) -> Result { - let mut creators: Vec = Vec::new(); - let mut share = 0u32; + // let mut creators: Vec = Vec::new(); + // let mut share = 0u32; - for creator in &config.creators { - let c = creator.to_candy_format()?; - share += c.percentage_share as u32; + // for creator in &config.creators { + // let c = creator.to_candy_format()?; + // share += c.percentage_share as u32; - creators.push(c); - } + // creators.push(c); + // } - if creators.is_empty() || creators.len() > (MAX_CREATOR_LIMIT - 1) { - return Err(anyhow!( - "The number of creators must be between 1 and {}.", - MAX_CREATOR_LIMIT - 1, - )); - } + // if creators.is_empty() { + // return Err(anyhow!("The number of creators must be greater than 1.")); + // } - if share != 100 { - return Err(anyhow!( - "Creator(s) share must add up to 100, current total {}.", - share, - )); - } + // if share != 100 { + // return Err(anyhow!( + // "Creator(s) share must add up to 100, current total {}.", + // share, + // )); + // } let config_line_settings = if config.hidden_settings.is_some() { None @@ -119,11 +105,8 @@ pub fn create_candy_machine_data( let data = CandyMachineData { items_available: config.number, - symbol: config.symbol.clone(), - seller_fee_basis_points: config.seller_fee_basis_points, max_supply: config.max_edition_supply.unwrap_or(0), is_mutable: config.is_mutable, - creators, config_line_settings, hidden_settings, }; @@ -133,7 +116,7 @@ pub fn create_candy_machine_data( /// Send the `initialize_candy_machine` instruction to the candy machine program. pub fn initialize_candy_machine + Clone>( - config_data: &ConfigData, + _config_data: &ConfigData, candy_account: &Keypair, candy_machine_data: CandyMachineData, collection_mint: Pubkey, @@ -168,14 +151,7 @@ pub fn initialize_candy_machine + Clone>( let (authority_pda, _) = find_candy_machine_creator_pda(&candy_account.pubkey()); - let collection_metadata = find_metadata_pda(&collection_mint); - let collection_master_edition = find_master_edition_pda(&collection_mint); - let (collection_delegate_record, _) = find_metadata_delegate_record_account( - &collection_mint, - MetadataDelegateRole::Collection, - &collection_update_authority, - &authority_pda, - ); + // let collection = get_base_collection(&collection_mint, &program)?; let priority_fee_ix = ComputeBudgetInstruction::set_compute_unit_price(*priority_fee); @@ -190,28 +166,19 @@ pub fn initialize_candy_machine + Clone>( &program.id(), )) .signer(candy_account) - .accounts(nft_accounts::InitializeV2 { + .accounts(nft_accounts::Initialize { candy_machine: candy_account.pubkey(), - authority: payer, authority_pda, + authority: payer, payer, - collection_metadata, - collection_mint, - collection_master_edition, + collection: collection_mint, collection_update_authority, - collection_delegate_record, - rule_set: config_data.rule_set, - token_metadata_program: mpl_token_metadata::ID, + mpl_core_program: mpl_core::ID, system_program: system_program::id(), sysvar_instructions: sysvar::instructions::ID, - authorization_rules_program: None, - authorization_rules: None, }) - .args(nft_instruction::InitializeV2 { + .args(nft_instruction::Initialize { data: candy_machine_data, - token_standard: >::into(config_data.token_standard) as u8, }); let sig = tx.send()?; diff --git a/src/deploy/process.rs b/src/deploy/process.rs index 1e74b52e..aa8cca38 100644 --- a/src/deploy/process.rs +++ b/src/deploy/process.rs @@ -14,7 +14,6 @@ use anchor_client::solana_sdk::{ }; use anyhow::Result; use console::style; -use mpl_token_metadata::state::{Metadata, TokenMetadataAccount}; use crate::{ cache::*, @@ -26,11 +25,10 @@ use crate::{ initialize_candy_machine, upload_config_lines, }, hash::hash_and_update, - pdas::find_metadata_pda, setup::{setup_client, sugar_setup}, update::{process_update, UpdateArgs}, utils::*, - validate::parser::{check_name, check_seller_fee_basis_points, check_symbol, check_url}, + validate::parser::check_seller_fee_basis_points, }; pub struct DeployArgs { @@ -66,14 +64,10 @@ pub async fn process_deploy(args: DeployArgs) -> Result<()> { for (index, item) in &cache.items.0 { if item.name.is_empty() { return Err(DeployError::MissingName(index.to_string()).into()); - } else { - check_name(&item.name)?; } if item.metadata_link.is_empty() { return Err(DeployError::MissingMetadataLink(index.to_string()).into()); - } else { - check_url(&item.metadata_link)?; } } @@ -99,7 +93,6 @@ pub async fn process_deploy(args: DeployArgs) -> Result<()> { cache_items_sans_collection )); } else { - check_symbol(&config_data.symbol)?; check_seller_fee_basis_points(config_data.seller_fee_basis_points)?; } @@ -169,20 +162,18 @@ pub async fn process_deploy(args: DeployArgs) -> Result<()> { spinner.set_message("Creating candy machine..."); let candy_data = create_candy_machine_data(&client, &config_data, &cache)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; // all good, let's create the candy machine - let collection_metadata = find_metadata_pda(&collection_mint); - let data = program.rpc().get_account_data(&collection_metadata)?; - let metadata = Metadata::safe_deserialize(data.as_slice())?; + let collection = get_base_collection(&collection_mint, &program)?; let sig = initialize_candy_machine( &config_data, &candy_keypair, candy_data, collection_mint, - metadata.update_authority, + collection.update_authority, program, &args.priority_fee, )?; diff --git a/src/freeze/initialize.rs b/src/freeze/initialize.rs index addc0b64..0ee01143 100644 --- a/src/freeze/initialize.rs +++ b/src/freeze/initialize.rs @@ -3,7 +3,7 @@ use std::ops::Deref; use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use mpl_candy_guard::{ +use mpl_core_candy_guard::{ accounts::Route as RouteAccount, guards::FreezeInstruction, instruction::Route, instructions::RouteArgs, state::GuardType, }; @@ -25,7 +25,7 @@ pub struct InitializeArgs { pub fn process_initialize(args: InitializeArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair.clone(), args.rpc_url.clone())?; let client = setup_client(&sugar_config)?; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; // candy guard id specified takes precedence over the one from the cache let candy_guard_id = match args.candy_guard { diff --git a/src/freeze/mod.rs b/src/freeze/mod.rs index 682613ca..b23353b5 100644 --- a/src/freeze/mod.rs +++ b/src/freeze/mod.rs @@ -6,15 +6,14 @@ use std::{ use anchor_client::solana_sdk::pubkey::Pubkey; use anyhow::Result; use console::style; -use mpl_candy_guard::{ +use mpl_core_candy_guard::{ guards::FreezeEscrow, state::{CandyGuardData, DATA_OFFSET}, }; use serde::{Deserialize, Serialize, Serializer}; -use solana_client::{rpc_client::RpcClient, rpc_request::RpcRequest}; +use solana_client::rpc_client::RpcClient; use solana_program::{instruction::AccountMeta, program_pack::Pack}; use spl_associated_token_account::get_associated_token_address; -use spl_token::state::Account as SplAccount; use tokio::sync::Semaphore; use crate::{ @@ -23,9 +22,7 @@ use crate::{ config::{get_config_data, Cluster, ConfigData, SugarConfig}, pdas::*, setup::get_rpc_url, - utils::{ - get_cluster, get_cm_creator_mint_accounts, progress_bar_with_style, spinner_with_style, - }, + utils::{get_cluster, progress_bar_with_style, spinner_with_style}, }; mod initialize; @@ -48,7 +45,7 @@ pub fn find_freeze_pda( candy_machine_id.as_ref(), ]; - Pubkey::find_program_address(freeze_seeds, &mpl_candy_guard::ID) + Pubkey::find_program_address(freeze_seeds, &mpl_core_candy_guard::ID) } pub fn get_destination + Clone>( diff --git a/src/freeze/thaw.rs b/src/freeze/thaw.rs index 208a7e87..2855fd85 100644 --- a/src/freeze/thaw.rs +++ b/src/freeze/thaw.rs @@ -3,17 +3,14 @@ use std::{fmt::Display, time::Duration}; use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use mpl_candy_guard::{ +use mpl_core::Asset; +use mpl_core_candy_guard::{ accounts::Route as RouteAccount, guards::FreezeInstruction, instruction::Route, instructions::RouteArgs, state::GuardType, }; -use mpl_token_metadata::{ - pda::find_token_record_account, - state::{Metadata, ProgrammableConfig, TokenMetadataAccount, TokenRecord}, -}; use super::*; -use crate::config::TokenStandard; +use crate::{candy_machine::get_candy_machine_state, utils::get_cm_mint_accounts}; pub struct ThawArgs { pub keypair: Option, @@ -45,11 +42,7 @@ struct ThawNft { #[serde(serialize_with = "serialize_pubkey")] owner: Pubkey, #[serde(serialize_with = "serialize_pubkey")] - token_account: Pubkey, - #[serde(default)] - token_standard: TokenStandard, - #[serde(serialize_with = "serialize_option_pubkey")] - rule_set: Option, + collection: Pubkey, } fn serialize_pubkey(p: &Pubkey, serializer: S) -> Result @@ -70,26 +63,26 @@ where } } -#[derive(Debug, Deserialize)] -pub struct JRpcResponse { - value: Vec, -} +// #[derive(Debug, Deserialize)] +// pub struct JRpcResponse { +// value: Vec, +// } -#[derive(Debug, Deserialize)] -struct TokenAccount { - address: String, - amount: String, -} +// #[derive(Debug, Deserialize)] +// struct TokenAccount { +// address: String, +// amount: String, +// } // Default timeout for 300 seconds (5 minutes). const DEFAULT_TIMEOUT: u64 = 300; pub async fn process_thaw(args: ThawArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair.clone(), args.rpc_url.clone())?; - let client = setup_client(&sugar_config)?; - let program = client.program(mpl_candy_guard::ID); - let rpc_url = get_rpc_url(args.rpc_url.clone()); - let rpc_client = RpcClient::new(&rpc_url); + let client: Client> = setup_client(&sugar_config)?; + let program = client.program(mpl_core_candy_guard::ID)?; + // let rpc_url = get_rpc_url(args.rpc_url.clone()); + // let rpc_client = RpcClient::new(&rpc_url); // candy guard id specified takes precedence over the one from the cache let candy_guard_id = match args.candy_guard { @@ -175,6 +168,8 @@ pub async fn process_thaw(args: ThawArgs) -> Result<()> { pb.finish_with_message("Done"); + let candy_machine_state = get_candy_machine_state(&sugar_config, &candy_machine)?; + if !args.all { println!( "\n{} {}Thawing NFT", @@ -193,96 +188,59 @@ pub async fn process_thaw(args: ThawArgs) -> Result<()> { let config = Arc::new(sugar_config); - let request = RpcRequest::Custom { - method: "getTokenLargestAccounts", - }; - let params = json!([nft_mint, { "commitment": "confirmed" }]); - let result: JRpcResponse = rpc_client.send(request, params).unwrap(); - - let token_accounts: Vec = result - .value - .into_iter() - .filter(|account| account.amount.parse::().unwrap() == 1) - .collect(); - - if token_accounts.len() > 1 { - return Err(anyhow!( - "Mint account {} had more than one token account with 1 token", - nft_mint - )); - } - - if token_accounts.is_empty() { - return Err(anyhow!( - "Mint account {} had zero token accounts with 1 token", - nft_mint - )); - } - - let token_account = Pubkey::from_str(&token_accounts[0].address).unwrap(); + // let request = RpcRequest::Custom { + // method: "getTokenLargestAccounts", + // }; + // let params = json!([nft_mint, { "commitment": "confirmed" }]); + // let result: JRpcResponse = rpc_client.send(request, params).unwrap(); + + // let token_accounts: Vec = result + // .value + // .into_iter() + // .filter(|account| account.amount.parse::().unwrap() == 1) + // .collect(); + + // if token_accounts.len() > 1 { + // return Err(anyhow!( + // "Mint account {} had more than one token account with 1 token", + // nft_mint + // )); + // } + + // if token_accounts.is_empty() { + // return Err(anyhow!( + // "Mint account {} had zero token accounts with 1 token", + // nft_mint + // )); + // } let account = program .rpc() - .get_account_with_commitment(&token_account, CommitmentConfig::confirmed()) + .get_account_with_commitment(&nft_mint_pubkey, CommitmentConfig::confirmed()) .unwrap() .value .unwrap(); - let account_data = SplAccount::unpack(&account.data).unwrap(); - let owner = account_data.owner; + let account_data = Asset::deserialize(&account.data).unwrap(); + let owner = account_data.base.owner; // Only thaw frozen accounts. - let (locked, token_standard, rule_set) = if account_data.is_frozen() { - // We need to determine whether we have a NFT or pNFT. - let token_record_pubkey = find_token_record_account(&nft_mint_pubkey, &token_account).0; - if let Some(token_record) = rpc_client - .get_account_with_commitment(&token_record_pubkey, CommitmentConfig::confirmed()) + let frozen = account_data.plugin_list.freeze_delegate.is_some() + && account_data + .plugin_list + .freeze_delegate .unwrap() - .value - { - let token_record = TokenRecord::safe_deserialize(&token_record.data).unwrap(); - - if token_record.is_locked() { - let metadata_pubkey = find_metadata_pda(&nft_mint_pubkey); - let metadata_account = rpc_client - .get_account_with_commitment( - &metadata_pubkey, - CommitmentConfig::confirmed(), - ) - .unwrap() - .value - .unwrap(); - let metadata = Metadata::safe_deserialize(&metadata_account.data).unwrap(); - - let rule_set = if let Some(ProgrammableConfig::V1 { rule_set }) = - metadata.programmable_config - { - rule_set - } else { - None - }; - - (true, TokenStandard::ProgrammableNonFungible, rule_set) - } else { - (false, TokenStandard::ProgrammableNonFungible, None) - } - } else { - (true, TokenStandard::NonFungible, None) - } - } else { - (false, TokenStandard::NonFungible, None) - }; + .freeze_delegate + .frozen; - if !locked { - println!("\n NFT is already thawed."); + if !frozen { + println!("\n Asset is already thawed."); return Ok(()); } let nft = ThawNft { mint: nft_mint_pubkey, - token_account, owner, - token_standard, - rule_set, + collection: candy_machine_state.collection_mint, }; let pb = spinner_with_style(); @@ -319,7 +277,7 @@ pub async fn process_thaw(args: ThawArgs) -> Result<()> { pb.set_message("Searching..."); let solana_cluster: Cluster = get_cluster(program.rpc())?; - let rpc_url = get_rpc_url(args.rpc_url); + let rpc_url = get_rpc_url(args.rpc_url.clone()); let client = RpcClient::new_with_timeout( &rpc_url, Duration::from_secs(if let Some(timeout) = args.timeout { @@ -353,7 +311,7 @@ pub async fn process_thaw(args: ThawArgs) -> Result<()> { Cluster::Devnet | Cluster::Localnet | Cluster::Mainnet => { let (creator, _) = find_candy_machine_creator_pda(&candy_machine); let creator = bs58::encode(creator).into_string(); - get_cm_creator_mint_accounts(&client, &creator, 0)? + get_cm_mint_accounts(&client, &creator)? } _ => { return Err(anyhow!( @@ -386,7 +344,7 @@ pub async fn process_thaw(args: ThawArgs) -> Result<()> { pb.set_message("Getting NFT information...."); let semaphore = Arc::new(Semaphore::new(100)); - let client = Arc::new(client); + // let client = Arc::new(client); let mut tasks = Vec::new(); let mut thaw_tasks = Vec::new(); @@ -399,97 +357,45 @@ pub async fn process_thaw(args: ThawArgs) -> Result<()> { for mint in mint_pubkeys { let permit = Arc::clone(&semaphore).acquire_owned().await.unwrap(); - let client = client.clone(); + // let client = client.clone(); let pb = pb.clone(); - let errors = errors.clone(); + // let errors = errors.clone(); let thaw_nfts = thaw_nfts.clone(); + // let rc_keypair = Rc::try_unwrap(program.payer().clone()).unwrap_or_else(|rc| (*rc).clone()); + let sugar_config = sugar_setup(args.keypair.clone(), args.rpc_url.clone()).unwrap(); + let client = setup_async_client(&sugar_config).unwrap(); + let program = client.program(mpl_core_candy_guard::ID).unwrap(); tasks.push(tokio::spawn(async move { let _permit = permit; - let request = RpcRequest::Custom { - method: "getTokenLargestAccounts", - }; - let params = json!([mint.to_string(), { "commitment": "confirmed" }]); - let result: JRpcResponse = client.send(request, params).unwrap(); - - let token_accounts: Vec = result - .value - .into_iter() - .filter(|account| account.amount.parse::().unwrap() == 1) - .collect(); - - if token_accounts.len() != 1 { - errors.lock().unwrap().push(anyhow!( - "Mint account {} had more than one token account with 1 token", - mint - )); - return; - } - - let token_account = Pubkey::from_str(&token_accounts[0].address).unwrap(); - let account = client - .get_account_with_commitment(&token_account, CommitmentConfig::confirmed()) + let account = program + .rpc() + .get_account_with_commitment(&mint, CommitmentConfig::confirmed()) .unwrap() .value .unwrap(); - let account_data = SplAccount::unpack(&account.data).unwrap(); - let owner = account_data.owner; + let account_data = Asset::deserialize(&account.data).unwrap(); + let owner = account_data.base.owner; // Only thaw frozen accounts. - if account_data.is_frozen() { - // We need to determine whether we have a NFT or pNFT. - let token_record_pubkey = find_token_record_account(&mint, &token_account).0; - let (locked, token_standard, rule_set) = if let Some(token_record) = client - .get_account_with_commitment( - &token_record_pubkey, - CommitmentConfig::confirmed(), - ) + let frozen = account_data.plugin_list.freeze_delegate.is_some() + && account_data + .plugin_list + .freeze_delegate .unwrap() - .value - { - let token_record = TokenRecord::safe_deserialize(&token_record.data).unwrap(); - - if token_record.is_locked() { - let metadata_pubkey = find_metadata_pda(&mint); - let metadata_account = client - .get_account_with_commitment( - &metadata_pubkey, - CommitmentConfig::confirmed(), - ) - .unwrap() - .value - .unwrap(); - let metadata = Metadata::safe_deserialize(&metadata_account.data).unwrap(); - - let rule_set = if let Some(ProgrammableConfig::V1 { rule_set }) = - metadata.programmable_config - { - rule_set - } else { - None - }; - - (true, TokenStandard::ProgrammableNonFungible, rule_set) - } else { - (false, TokenStandard::ProgrammableNonFungible, None) - } - } else { - (true, TokenStandard::NonFungible, None) - }; - - if locked { - thaw_nfts.lock().unwrap().push(ThawNft { - mint, - token_account, - owner, - token_standard, - rule_set, - }); - } - - pb.inc(1); + .freeze_delegate + .frozen; + + if frozen { + thaw_nfts.lock().unwrap().push(ThawNft { + mint, + owner, + collection: candy_machine_state.collection_mint, + }); } + + pb.inc(1); })); } @@ -602,7 +508,7 @@ fn thaw_nft( priority_fee: &u64, ) -> Result { let client = setup_client(&config)?; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; let mut remaining_accounts = Vec::with_capacity(7); let (freeze_pda, _) = find_freeze_pda(candy_guard_id, candy_machine_id, destination); @@ -617,86 +523,20 @@ fn thaw_nft( is_writable: false, }); remaining_accounts.push(AccountMeta { - pubkey: nft.owner, - is_signer: false, - is_writable: false, - }); - remaining_accounts.push(AccountMeta { - pubkey: nft.token_account, + pubkey: nft.collection, is_signer: false, is_writable: true, }); remaining_accounts.push(AccountMeta { - pubkey: find_master_edition_pda(&nft.mint), + pubkey: mpl_core::ID, is_signer: false, is_writable: false, }); remaining_accounts.push(AccountMeta { - pubkey: spl_token::ID, + pubkey: system_program::ID, is_signer: false, is_writable: false, }); - remaining_accounts.push(AccountMeta { - pubkey: Pubkey::from_str(METAPLEX_PROGRAM_ID)?, - is_signer: false, - is_writable: false, - }); - - // pnft specific - - if matches!(nft.token_standard, TokenStandard::ProgrammableNonFungible) { - let freeze_token_account = get_associated_token_address(&freeze_pda, &nft.mint); - - remaining_accounts.push(AccountMeta { - pubkey: find_metadata_pda(&nft.mint), - is_signer: false, - is_writable: true, - }); - remaining_accounts.push(AccountMeta { - pubkey: freeze_token_account, - is_signer: false, - is_writable: true, - }); - remaining_accounts.push(AccountMeta { - pubkey: system_program::ID, - is_signer: false, - is_writable: false, - }); - remaining_accounts.push(AccountMeta { - pubkey: sysvar::instructions::ID, - is_signer: false, - is_writable: false, - }); - remaining_accounts.push(AccountMeta { - pubkey: spl_associated_token_account::ID, - is_signer: false, - is_writable: false, - }); - remaining_accounts.push(AccountMeta { - pubkey: find_token_record_account(&nft.mint, &nft.token_account).0, - is_signer: false, - is_writable: true, - }); - remaining_accounts.push(AccountMeta { - pubkey: find_token_record_account(&nft.mint, &freeze_token_account).0, - is_signer: false, - is_writable: true, - }); - remaining_accounts.push(AccountMeta { - pubkey: mpl_token_auth_rules::ID, - is_signer: false, - is_writable: false, - }); - remaining_accounts.push(AccountMeta { - pubkey: if let Some(rule_set) = nft.rule_set { - rule_set - } else { - mpl_token_metadata::ID - }, - is_signer: false, - is_writable: false, - }); - } let priority_fee_ix = ComputeBudgetInstruction::set_compute_unit_price(*priority_fee); diff --git a/src/freeze/unlock_funds.rs b/src/freeze/unlock_funds.rs index ad99d5cb..4805d895 100644 --- a/src/freeze/unlock_funds.rs +++ b/src/freeze/unlock_funds.rs @@ -1,5 +1,5 @@ use anchor_client::solana_sdk::compute_budget::ComputeBudgetInstruction; -use mpl_candy_guard::{ +use mpl_core_candy_guard::{ accounts::Route as RouteAccount, guards::FreezeInstruction, instruction::Route, instructions::RouteArgs, state::GuardType, }; @@ -22,7 +22,7 @@ pub struct UnlockFundsArgs { pub fn process_unlock_funds(args: UnlockFundsArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair.clone(), args.rpc_url.clone())?; let client = setup_client(&sugar_config)?; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; // candy guard id specified takes precedence over the one from the cache let candy_guard_id = match args.candy_guard { diff --git a/src/guard/add.rs b/src/guard/add.rs index d66d2dad..f0b522c0 100644 --- a/src/guard/add.rs +++ b/src/guard/add.rs @@ -3,11 +3,11 @@ use std::str::FromStr; use anchor_client::solana_sdk::{compute_budget::ComputeBudgetInstruction, pubkey::Pubkey}; use anyhow::Result; use console::style; -use mpl_candy_guard::{ +use mpl_core_candy_guard::{ accounts::{Initialize as InitializeAccount, Update as UpdateAccount, Wrap as WrapAccount}, instruction::{Initialize, Update, Wrap}, }; -use mpl_candy_machine_core::constants::EMPTY_STR; +use mpl_core_candy_machine_core::constants::EMPTY_STR; use crate::{cache::load_cache, candy_machine::*, common::*, config::get_config_data, utils::*}; @@ -71,7 +71,7 @@ pub fn process_guard_add(args: GuardAddArgs) -> Result<()> { let config_data = get_config_data(&args.config)?; let client = setup_client(&sugar_config)?; let payer = sugar_config.keypair; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; let candy_guard = if candy_guard_id.is_empty() { println!("\n[2/3] {}Initializing a candy guard", GUARD_EMOJI); @@ -87,7 +87,7 @@ pub fn process_guard_add(args: GuardAddArgs) -> Result<()> { let base = Keypair::new(); let (candy_guard, _) = Pubkey::find_program_address( &[b"candy_guard", base.pubkey().as_ref()], - &mpl_candy_guard::ID, + &mpl_core_candy_guard::ID, ); let mut serialized_data = vec![0; data.size()]; diff --git a/src/guard/remove.rs b/src/guard/remove.rs index e3a12db5..cf1e3a08 100644 --- a/src/guard/remove.rs +++ b/src/guard/remove.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use anchor_client::solana_sdk::{compute_budget::ComputeBudgetInstruction, pubkey::Pubkey}; use anyhow::Result; use console::style; -use mpl_candy_guard::{accounts::Unwrap as UnwrapAccount, instruction::Unwrap}; +use mpl_core_candy_guard::{accounts::Unwrap as UnwrapAccount, instruction::Unwrap}; use crate::{cache::load_cache, candy_machine::*, common::*, utils::*}; @@ -59,7 +59,7 @@ pub fn process_guard_remove(args: GuardRemoveArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; let payer = sugar_config.keypair; let pb = spinner_with_style(); diff --git a/src/guard/show.rs b/src/guard/show.rs index 69168204..2cb02a45 100644 --- a/src/guard/show.rs +++ b/src/guard/show.rs @@ -4,8 +4,8 @@ use anchor_client::solana_sdk::pubkey::Pubkey; use anyhow::Result; use chrono::NaiveDateTime; use console::style; -use mpl_candy_guard::state::{CandyGuard, CandyGuardData, GuardSet, DATA_OFFSET}; -use mpl_candy_machine_core::constants::EMPTY_STR; +use mpl_core_candy_guard::state::{CandyGuard, CandyGuardData, GuardSet, DATA_OFFSET}; +use mpl_core_candy_machine_core::constants::EMPTY_STR; use solana_program::native_token::LAMPORTS_PER_SOL; use crate::{cache::load_cache, common::*, show::print_with_style, utils::*}; @@ -44,7 +44,7 @@ pub fn process_guard_show(args: GuardShowArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; let pb = spinner_with_style(); pb.set_message("Connecting..."); diff --git a/src/guard/update.rs b/src/guard/update.rs index 27747856..1104e1cf 100644 --- a/src/guard/update.rs +++ b/src/guard/update.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use anchor_client::solana_sdk::{compute_budget::ComputeBudgetInstruction, pubkey::Pubkey}; use anyhow::Result; use console::style; -use mpl_candy_guard::{accounts::Update as UpdateAccount, instruction::Update}; +use mpl_core_candy_guard::{accounts::Update as UpdateAccount, instruction::Update}; use crate::{cache::load_cache, common::*, config::get_config_data, utils::*}; @@ -47,7 +47,7 @@ pub fn process_guard_update(args: GuardUpdateArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; let payer = sugar_config.keypair; let pb = spinner_with_style(); diff --git a/src/guard/withdraw.rs b/src/guard/withdraw.rs index 54d8d754..289721e4 100644 --- a/src/guard/withdraw.rs +++ b/src/guard/withdraw.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use anchor_client::solana_sdk::{compute_budget::ComputeBudgetInstruction, pubkey::Pubkey}; use anyhow::Result; use console::style; -use mpl_candy_guard::{accounts::Withdraw as WithdrawAccount, instruction::Withdraw}; +use mpl_core_candy_guard::{accounts::Withdraw as WithdrawAccount, instruction::Withdraw}; use solana_program::native_token::LAMPORTS_PER_SOL; use crate::{cache::load_cache, common::*, utils::*}; @@ -43,7 +43,7 @@ pub fn process_guard_withdraw(args: GuardWithdrawArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(mpl_candy_guard::ID); + let program = client.program(mpl_core_candy_guard::ID)?; let payer = sugar_config.keypair; let pb = spinner_with_style(); diff --git a/src/lib.rs b/src/lib.rs index fddb6218..867dd78c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,7 +21,6 @@ pub mod program_errors; pub mod reveal; pub mod setup; pub mod show; -pub mod sign; pub mod update; pub mod upload; pub mod utils; diff --git a/src/main.rs b/src/main.rs index 3cb87a4c..6f614a93 100644 --- a/src/main.rs +++ b/src/main.rs @@ -34,8 +34,7 @@ use sugar_cli::{ parse::parse_sugar_errors, reveal::{process_reveal, RevealArgs}, show::{process_show, ShowArgs}, - sign::{process_sign, SignArgs}, - update::{process_set_token_stardard, process_update, SetTokenStandardArgs, UpdateArgs}, + update::{process_update, UpdateArgs}, upload::{process_upload, UploadArgs}, validate::{process_validate, ValidateArgs}, verify::{process_verify, VerifyArgs}, @@ -53,6 +52,7 @@ fn setup_logging(level: Option) -> Result<()> { let file = OpenOptions::new() .write(true) .create(true) + .truncate(true) .open(log_path) .unwrap(); @@ -202,23 +202,6 @@ async fn run() -> Result<()> { candy_machine, priority_fee, })?, - ConfigSubcommands::Set { - keypair, - rpc_url, - cache, - token_standard, - candy_machine, - rule_set, - priority_fee, - } => process_set_token_stardard(SetTokenStandardArgs { - keypair, - rpc_url, - cache, - token_standard, - candy_machine, - rule_set, - priority_fee, - })?, }, Commands::Deploy { config, @@ -543,22 +526,6 @@ async fn run() -> Result<()> { authority, priority_fee, })?, - Commands::Sign { - keypair, - rpc_url, - cache, - mint, - candy_machine_id, - } => { - process_sign(SignArgs { - keypair, - rpc_url, - cache, - mint, - candy_machine_id, - }) - .await? - } } Ok(()) diff --git a/src/mint/process.rs b/src/mint/process.rs index ea0dc55f..fa7f52c7 100644 --- a/src/mint/process.rs +++ b/src/mint/process.rs @@ -8,20 +8,11 @@ use anchor_client::solana_sdk::{ }; use anyhow::Result; use console::style; -use mpl_candy_machine_core::{ - accounts as nft_accounts, instruction as nft_instruction, AccountVersion, CandyMachine, -}; -use mpl_token_metadata::{ - instruction::MetadataDelegateRole, - pda::{ - find_collection_authority_account, find_metadata_delegate_record_account, - find_token_record_account, - }, - state::{Metadata, TokenMetadataAccount}, +use mpl_core_candy_machine_core::{ + accounts as nft_accounts, candy_machine::MintAssetArgs, instruction as nft_instruction, + CandyMachine, }; use solana_client::rpc_response::Response; -use spl_associated_token_account::get_associated_token_address; -use spl_token::ID as TOKEN_PROGRAM_ID; use tokio::sync::Semaphore; use crate::{ @@ -46,7 +37,7 @@ pub struct MintArgs { pub async fn process_mint(args: MintArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; // the candy machine id specified takes precedence over the one from the cache @@ -78,9 +69,8 @@ pub async fn process_mint(args: MintArgs) -> Result<()> { pb.set_message("Connecting..."); let candy_machine_state = Arc::new(get_candy_machine_state(&sugar_config, &candy_pubkey)?); - let (_, collection_metadata) = - get_metadata_pda(&candy_machine_state.collection_mint, &program)?; - let collection_update_authority = collection_metadata.update_authority; + let collection = get_base_collection(&candy_machine_state.collection_mint, &program)?; + let collection_update_authority = collection.update_authority; pb.finish_with_message("Done"); @@ -205,12 +195,12 @@ pub async fn mint( config: Arc, candy_machine_id: Pubkey, candy_machine_state: Arc, - collection_update_authority: Pubkey, + _collection_update_authority: Pubkey, receiver: Pubkey, priority_fee: u64, ) -> Result<(Signature, Pubkey)> { let client = setup_client(&config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let payer = program.payer(); if candy_machine_state.mint_authority != payer { @@ -220,72 +210,63 @@ pub async fn mint( } let nft_mint = Keypair::new(); - let metaplex_program_id = Pubkey::from_str(METAPLEX_PROGRAM_ID)?; - // derive associated token account - let token = get_associated_token_address(&receiver, &nft_mint.pubkey()); - let collection_mint = candy_machine_state.collection_mint; + // let collection_mint = candy_machine_state.collection_mint; let (authority_pda, _) = find_candy_machine_creator_pda(&candy_machine_id); - let (token_record, collection_delegate_record) = - if matches!(candy_machine_state.version, AccountVersion::V1) { - ( - None, - find_collection_authority_account(&collection_mint, &authority_pda).0, - ) - } else { - ( - Some(find_token_record_account(&nft_mint.pubkey(), &token).0), - find_metadata_delegate_record_account( - &collection_mint, - MetadataDelegateRole::Collection, - &collection_update_authority, - &authority_pda, - ) - .0, - ) - }; - - let collection_metadata = find_metadata_pda(&collection_mint); - - let data = program.rpc().get_account_data(&collection_metadata)?; - let metadata = Metadata::safe_deserialize(data.as_slice())?; - - let metadata_pda = find_metadata_pda(&nft_mint.pubkey()); - let master_edition_pda = find_master_edition_pda(&nft_mint.pubkey()); + // let collection = get_base_collection(&collection_mint, &program)?; + + // let mint_ix = program + // .request() + // .accounts(nft_accounts::MintV2 { + // candy_machine: candy_machine_id, + // authority_pda, + // payer, + // nft_owner: receiver, + // token: Some(token), + // token_record, + // mint_authority: payer, + // nft_metadata: metadata_pda, + // nft_mint: nft_mint.pubkey(), + // nft_master_edition: master_edition_pda, + // nft_mint_authority: payer, + // collection_mint: candy_machine_state.collection_mint, + // collection_metadata: find_metadata_pda(&candy_machine_state.collection_mint), + // collection_master_edition: find_master_edition_pda( + // &candy_machine_state.collection_mint, + // ), + // collection_delegate_record, + // collection_update_authority: metadata.update_authority, + // token_metadata_program: metaplex_program_id, + // spl_token_program: TOKEN_PROGRAM_ID, + // spl_ata_program: Some(spl_associated_token_account::ID), + // system_program: system_program::id(), + // sysvar_instructions: sysvar::instructions::ID, + // recent_slothashes: sysvar::slot_hashes::ID, + // authorization_rules_program: None, + // authorization_rules: None, + // }) + // .args(nft_instruction::MintV2 {}); let mint_ix = program .request() - .accounts(nft_accounts::MintV2 { + .accounts(nft_accounts::MintAsset { candy_machine: candy_machine_id, authority_pda, - payer, - nft_owner: receiver, - token: Some(token), - token_record, mint_authority: payer, - nft_metadata: metadata_pda, - nft_mint: nft_mint.pubkey(), - nft_master_edition: master_edition_pda, - nft_mint_authority: payer, - collection_mint: candy_machine_state.collection_mint, - collection_metadata: find_metadata_pda(&candy_machine_state.collection_mint), - collection_master_edition: find_master_edition_pda( - &candy_machine_state.collection_mint, - ), - collection_delegate_record, - collection_update_authority: metadata.update_authority, - token_metadata_program: metaplex_program_id, - spl_token_program: TOKEN_PROGRAM_ID, - spl_ata_program: Some(spl_associated_token_account::ID), - system_program: system_program::id(), + payer, + asset_owner: receiver, + asset: nft_mint.pubkey(), + collection: candy_machine_state.collection_mint, + mpl_core_program: mpl_core::ID, + system_program: system_program::ID, sysvar_instructions: sysvar::instructions::ID, recent_slothashes: sysvar::slot_hashes::ID, - authorization_rules_program: None, - authorization_rules: None, }) - .args(nft_instruction::MintV2 {}); + .args(nft_instruction::MintAsset { + args: MintAssetArgs { plugins: vec![] }, + }); let mut mint_ix = mint_ix.instructions()?; @@ -311,7 +292,7 @@ pub async fn mint( if let Err(_) | Ok(Response { value: None, .. }) = program .rpc() - .get_account_with_commitment(&metadata_pda, CommitmentConfig::processed()) + .get_account_with_commitment(&nft_mint.pubkey(), CommitmentConfig::processed()) { let cluster_param = match get_cluster(program.rpc()).unwrap_or(Cluster::Mainnet) { Cluster::Devnet => "?devnet", diff --git a/src/pdas.rs b/src/pdas.rs index 606b73e4..8a7d0d9e 100644 --- a/src/pdas.rs +++ b/src/pdas.rs @@ -1,15 +1,4 @@ -use std::ops::Deref; - -use anchor_client::{ - solana_sdk::{pubkey::Pubkey, signer::Signer}, - Program, -}; -use anyhow::{anyhow, Result}; -use mpl_token_metadata::{ - pda::{find_master_edition_account, find_metadata_account}, - state::{Key, MasterEditionV2, Metadata, TokenMetadataAccount, MAX_MASTER_EDITION_LEN}, - utils::try_from_slice_checked, -}; +use anchor_client::solana_sdk::pubkey::Pubkey; use crate::candy_machine::CANDY_MACHINE_ID; @@ -20,68 +9,6 @@ pub struct CollectionPDA { pub candy_machine: Pubkey, } -pub fn find_metadata_pda(mint: &Pubkey) -> Pubkey { - let (pda, _bump) = find_metadata_account(mint); - - pda -} - -pub fn get_metadata_pda + Clone>( - mint: &Pubkey, - program: &Program, -) -> Result> { - let metadata_pubkey = find_metadata_pda(mint); - let metadata_account = program.rpc().get_account(&metadata_pubkey).map_err(|_| { - anyhow!( - "Couldn't find metadata account: {}", - &metadata_pubkey.to_string() - ) - })?; - let metadata = Metadata::safe_deserialize(metadata_account.data.as_slice()); - metadata.map(|m| (metadata_pubkey, m)).map_err(|_| { - anyhow!( - "Failed to deserialize metadata account: {}", - &metadata_pubkey.to_string() - ) - }) -} - -pub fn find_master_edition_pda(mint: &Pubkey) -> Pubkey { - let (pda, _bump) = find_master_edition_account(mint); - - pda -} - -pub fn get_master_edition_pda + Clone>( - mint: &Pubkey, - program: &Program, -) -> Result> { - let master_edition_pubkey = find_master_edition_pda(mint); - let master_edition_account = - program - .rpc() - .get_account(&master_edition_pubkey) - .map_err(|_| { - anyhow!( - "Couldn't find master edition account: {}", - &master_edition_pubkey.to_string() - ) - })?; - let master_edition = try_from_slice_checked( - master_edition_account.data.as_slice(), - Key::MasterEditionV2, - MAX_MASTER_EDITION_LEN, - ); - master_edition - .map(|m| (master_edition_pubkey, m)) - .map_err(|_| { - anyhow!( - "Invalid master edition account: {}", - &master_edition_pubkey.to_string() - ) - }) -} - pub fn find_candy_machine_creator_pda(candy_machine_id: &Pubkey) -> (Pubkey, u8) { // Derive metadata account let creator_seeds = &["candy_machine".as_bytes(), candy_machine_id.as_ref()]; diff --git a/src/reveal/process.rs b/src/reveal/process.rs index c7f25cb8..d328b264 100644 --- a/src/reveal/process.rs +++ b/src/reveal/process.rs @@ -7,10 +7,9 @@ use anchor_client::solana_sdk::account::Account; use anchor_lang::AnchorDeserialize; use console::style; use futures::future::join_all; -use mpl_token_metadata::{ - instruction::update_metadata_accounts_v2, - state::{DataV2, Metadata}, - ID as TOKEN_METADATA_PROGRAM_ID, +use mpl_core::{ + accounts::BaseAssetV1, + instructions::{UpdateV1, UpdateV1InstructionArgs}, }; use serde::Serialize; use solana_client::{client_error::ClientError, rpc_client::RpcClient}; @@ -18,10 +17,9 @@ use tokio::sync::Semaphore; use crate::{ cache::load_cache, - candy_machine::CANDY_MACHINE_ID, + candy_machine::{get_candy_machine_state, CANDY_MACHINE_ID}, common::*, config::{get_config_data, Cluster}, - pdas::{find_candy_machine_creator_pda, find_metadata_pda}, setup::get_rpc_url, utils::*, }; @@ -35,9 +33,9 @@ pub struct RevealArgs { } #[derive(Clone, Debug)] -pub struct MetadataUpdateValues { - pub metadata_pubkey: Pubkey, - pub metadata: Metadata, +pub struct AssetUpdateValues { + pub asset_pubkey: Pubkey, + pub asset: BaseAssetV1, pub new_uri: String, pub new_name: String, pub index: String, @@ -45,7 +43,7 @@ pub struct MetadataUpdateValues { #[derive(Debug, Clone, PartialEq, Eq, Serialize)] struct RevealTx { - metadata_pubkey: Pubkey, + asset_pubkey: Pubkey, result: RevealResult, } @@ -80,7 +78,7 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { let cache = load_cache(&args.cache, false)?; let sugar_config = sugar_setup(args.keypair, args.rpc_url.clone())?; let anchor_client = setup_client(&sugar_config)?; - let program = anchor_client.program(CANDY_MACHINE_ID); + let program = anchor_client.program(CANDY_MACHINE_ID)?; let candy_machine_id = match Pubkey::from_str(&cache.program.candy_machine) { Ok(candy_machine_id) => candy_machine_id, @@ -114,6 +112,8 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { solana_cluster }; + let candy_machine = get_candy_machine_state(&sugar_config, &candy_machine_id)?; + let metadata_pubkeys = match solana_cluster { Cluster::Mainnet | Cluster::Devnet | Cluster::Localnet => { let client = RpcClient::new_with_timeout( @@ -124,8 +124,7 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { DEFAULT_TIMEOUT }), ); - let (creator, _) = find_candy_machine_creator_pda(&candy_machine_id); - get_cm_creator_metadata_accounts(&client, &creator.to_string(), 0)? + get_cm_mint_accounts(&client, &candy_machine.collection_mint.to_string())? } _ => { return Err(anyhow!( @@ -165,20 +164,27 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { // Get all metadata accounts. metadata_pubkeys.as_slice().chunks(100).for_each(|chunk| { let client = client.clone(); - futures.push(async move { async_get_multiple_accounts(client, chunk).await }); + futures.push(async move { + let accounts = async_get_multiple_accounts(client, chunk).await.unwrap(); + Ok::<_, anyhow::Error>(chunk.iter().zip(accounts).collect::>()) + }); }); let results = join_all(futures).await; let mut accounts = Vec::new(); for result in results { - let res = result.unwrap(); + let res = result + .unwrap() + .into_iter() + .map(|(p, a)| (p, a.unwrap())) + .collect::>(); accounts.extend(res); } - let metadata: Vec = accounts + let assets: Vec<(&Pubkey, BaseAssetV1)> = accounts .into_iter() - .map(|a| a.unwrap().data) - .map(|d| Metadata::deserialize(&mut d.as_slice()).unwrap()) + .map(|a| (a.0, a.1.data)) + .map(|(p, d)| (p, BaseAssetV1::deserialize(&mut d.as_slice()).unwrap())) .collect(); let patterns: Vec<&str> = hidden_settings.name.split('$').collect(); @@ -225,8 +231,8 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { let spinner = spinner_with_style(); spinner.set_message("Setting up transactions..."); - for m in metadata { - let name = m.data.name.trim_matches(char::from(0)).to_string(); + for a in assets { + let name = a.clone().1.name; let num = match pattern.captures(&name).map(|c| c[1].to_string()) { Some(num) => num, None => { @@ -244,7 +250,6 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { } }; - let metadata_pubkey = find_metadata_pda(&m.mint); let new_uri = nft_lookup .get(&num) .filter(|i| !i.on_chain) @@ -258,9 +263,9 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { .name .clone(); - update_values.push(MetadataUpdateValues { - metadata_pubkey, - metadata: m, + update_values.push(AssetUpdateValues { + asset_pubkey: *a.0, + asset: a.1, new_uri, new_name, index: num, @@ -291,9 +296,9 @@ pub async fn process_reveal(args: RevealArgs) -> Result<()> { tx_tasks.push(tokio::spawn(async move { // Move permit into the closure so it is dropped when the task is dropped. let _permit = permit; - let metadata_pubkey = item.metadata_pubkey; + let asset_pubkey = item.asset_pubkey; let mut tx = RevealTx { - metadata_pubkey, + asset_pubkey, result: RevealResult::Success, }; @@ -351,32 +356,31 @@ async fn async_get_multiple_accounts( async fn update_metadata_value( client: Arc, update_authority: Arc, - value: MetadataUpdateValues, + value: AssetUpdateValues, ) -> Result<(), ClientError> { - let mut data = value.metadata.data; + let mut data = value.asset.clone(); if data.uri.trim_matches(char::from(0)) != value.new_uri.trim_matches(char::from(0)) { - data.uri = value.new_uri; - data.name = value.new_name; - - let data_v2 = DataV2 { - name: data.name, - symbol: data.symbol, - uri: data.uri, - seller_fee_basis_points: data.seller_fee_basis_points, - creators: data.creators, - collection: value.metadata.collection, - uses: value.metadata.uses, + data.uri.clone_from(&value.new_uri); + data.name.clone_from(&value.new_name); + + let update_authority_address = match value.clone().asset.update_authority { + mpl_core::types::UpdateAuthority::Collection(address) => Some(address), + _ => unreachable!(), }; - let ix = update_metadata_accounts_v2( - TOKEN_METADATA_PROGRAM_ID, - value.metadata_pubkey, - update_authority.pubkey(), - None, - Some(data_v2), - None, - None, - ); + let ix = UpdateV1 { + asset: value.asset_pubkey, + collection: update_authority_address, + payer: update_authority.pubkey(), + authority: None, + system_program: system_program::ID, + log_wrapper: None, + } + .instruction(UpdateV1InstructionArgs { + new_name: Some(value.new_name), + new_uri: Some(value.new_uri), + new_update_authority: None, + }); let recent_blockhash = client.get_latest_blockhash()?; let tx = Transaction::new_signed_with_payer( diff --git a/src/setup.rs b/src/setup.rs index 51a48253..938f5ae6 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -1,4 +1,4 @@ -use std::rc::Rc; +use std::{rc::Rc, sync::Arc}; use anchor_client::{ solana_sdk::{ @@ -14,6 +14,7 @@ use tracing::error; use crate::{config::data::SugarConfig, constants::DEFAULT_KEYPATH, parse::*}; pub type SugarClient = Client>; +pub type SugarAsyncClient = Client>; pub fn setup_client(sugar_config: &SugarConfig) -> Result { let rpc_url = sugar_config.rpc_url.clone(); @@ -27,6 +28,18 @@ pub fn setup_client(sugar_config: &SugarConfig) -> Result { Ok(Client::new_with_options(cluster, signer, opts)) } +pub fn setup_async_client(sugar_config: &SugarConfig) -> Result { + let rpc_url = sugar_config.rpc_url.clone(); + let ws_url = rpc_url.replace("http", "ws"); + let cluster = Cluster::Custom(rpc_url, ws_url); + + let key_bytes = sugar_config.keypair.to_bytes(); + let signer = Arc::new(Keypair::from_bytes(&key_bytes)?); + + let opts = CommitmentConfig::confirmed(); + Ok(Client::new_with_options(cluster, signer, opts)) +} + pub fn sugar_setup( keypair_opt: Option, rpc_url_opt: Option, diff --git a/src/show/process.rs b/src/show/process.rs index 7b6c3a47..0a0cde1c 100644 --- a/src/show/process.rs +++ b/src/show/process.rs @@ -3,11 +3,7 @@ use std::str::FromStr; use anchor_client::solana_sdk::pubkey::Pubkey; use anyhow::Result; use console::style; -use mpl_candy_machine_core::{ - constants::{HIDDEN_SECTION, NULL_STRING}, - AccountVersion, -}; -use mpl_token_metadata::state::TokenStandard; +use mpl_core_candy_machine_core::constants::HIDDEN_SECTION; use tabled::{ builder::Builder, settings::{object::Segment, Alignment, Modify, Style}, @@ -51,7 +47,7 @@ pub fn process_show(args: ShowArgs) -> Result<()> { let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let candy_machine_id = match Pubkey::from_str(&candy_machine_id) { Ok(candy_machine_id) => candy_machine_id, @@ -62,7 +58,7 @@ pub fn process_show(args: ShowArgs) -> Result<()> { } }; - let (cndy_state, rule_set) = load_candy_machine(&sugar_config, &candy_machine_id)?; + let cndy_state = load_candy_machine(&sugar_config, &candy_machine_id)?; let cndy_data = cndy_state.data; pb.finish_and_clear(); @@ -84,57 +80,13 @@ pub fn process_show(args: ShowArgs) -> Result<()> { "collection mint", cndy_state.collection_mint.to_string(), ); - - if matches!(cndy_state.version, AccountVersion::V1) { - print_with_style("", "account version", "V1"); - print_with_style("", "token standard", "NonFungible (NFT)"); - print_with_style("", "rule set", "none"); - } else { - print_with_style("", "account version", "V2"); - print_with_style( - "", - "token standard", - if cndy_state.token_standard == TokenStandard::NonFungible as u8 { - "NonFungible" - } else { - "ProgrammableNonFungible (pNFT)" - }, - ); - - if let Some(rule_set) = rule_set { - print_with_style("", "rule set", rule_set.to_string()); - } - } print_with_style("", "features", "none"); print_with_style("", "max supply", cndy_data.max_supply.to_string()); print_with_style("", "items redeemed", cndy_state.items_redeemed.to_string()); print_with_style("", "items available", cndy_data.items_available.to_string()); - print_with_style("", "symbol", cndy_data.symbol.trim_end_matches(NULL_STRING)); - print_with_style( - "", - "seller fee basis points", - format!( - "{}% ({})", - cndy_data.seller_fee_basis_points / 100, - cndy_data.seller_fee_basis_points - ), - ); print_with_style("", "is mutable", cndy_data.is_mutable.to_string()); - print_with_style("", "creators", "".to_string()); - - let creators = &cndy_data.creators; - - for (index, creator) in creators.iter().enumerate() { - let info = format!( - "{} ({}%{})", - creator.address, - creator.percentage_share, - if creator.verified { ", verified" } else { "" }, - ); - print_with_style(": ", &(index + 1).to_string(), info); - } // hidden settings diff --git a/src/sign/mod.rs b/src/sign/mod.rs deleted file mode 100644 index 6dc80e85..00000000 --- a/src/sign/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod process; - -pub use process::*; diff --git a/src/sign/process.rs b/src/sign/process.rs deleted file mode 100644 index 15528fec..00000000 --- a/src/sign/process.rs +++ /dev/null @@ -1,195 +0,0 @@ -use std::{str::FromStr, sync::Arc, time::Duration}; - -pub use anchor_client::{ - solana_sdk::{ - account::Account, - commitment_config::{CommitmentConfig, CommitmentLevel}, - native_token::LAMPORTS_PER_SOL, - pubkey::Pubkey, - signature::{Keypair, Signature, Signer}, - system_instruction, system_program, sysvar, - transaction::Transaction, - }, - Client, Program, -}; -use anyhow::Error; -use console::style; -use mpl_token_metadata::{instruction::sign_metadata, ID as METAPLEX_PROGRAM_ID}; -use retry::{delay::Exponential, retry}; -use solana_client::rpc_client::RpcClient; -use tokio::sync::Semaphore; - -use crate::{ - cache::load_cache, - candy_machine::CANDY_MACHINE_ID, - common::*, - config::{Cluster, SugarConfig}, - pdas::{find_candy_machine_creator_pda, find_metadata_pda}, - setup::{get_rpc_url, setup_client, sugar_setup}, - utils::*, -}; - -pub struct SignArgs { - pub candy_machine_id: Option, - pub keypair: Option, - pub cache: String, - pub rpc_url: Option, - pub mint: Option, -} - -pub async fn process_sign(args: SignArgs) -> Result<()> { - // (1) Setting up connection - println!( - "{} {}Initializing connection", - if args.mint.is_some() { - style("[1/2]").bold().dim() - } else { - style("[1/3]").bold().dim() - }, - COMPUTER_EMOJI - ); - - let pb = spinner_with_style(); - pb.set_message("Connecting..."); - - let sugar_config = Arc::new(sugar_setup(args.keypair, args.rpc_url.clone())?); - - let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); - - pb.finish_with_message("Connected"); - - if let Some(mint_id) = args.mint { - println!( - "\n{} {}Signing one NFT", - style("[2/2]").bold().dim(), - SIGNING_EMOJI, - ); - let pb = spinner_with_style(); - pb.set_message(format!("Signing NFT with mint id {}.", mint_id)); - - let account_pubkey = Pubkey::from_str(&mint_id)?; - let metadata_pubkey = find_metadata_pda(&account_pubkey); - match sign(Arc::clone(&sugar_config.clone()), metadata_pubkey).await { - Ok(signature) => format!("{} {:?}", style("Signature:").bold(), signature), - Err(err) => { - pb.abandon_with_message(format!("{}", style("Signing failed ").red().bold())); - error!("{:?}", err); - return Err(err); - } - }; - - pb.finish(); - } else { - println!( - "\n{} {}Fetching mint ids", - style("[2/3]").bold().dim(), - LOOKING_GLASS_EMOJI, - ); - - let mut errors = Vec::new(); - - let candy_machine_id = match args.candy_machine_id { - Some(candy_machine_id) => candy_machine_id, - None => { - let cache = load_cache(&args.cache, false)?; - cache.program.candy_machine - } - }; - - let candy_machine_id = Pubkey::from_str(&candy_machine_id) - .expect("Failed to parse pubkey from candy machine id."); - - let solana_cluster: Cluster = get_cluster(program.rpc())?; - let rpc_url = get_rpc_url(args.rpc_url); - - let solana_cluster = if rpc_url.ends_with("8899") { - Cluster::Localnet - } else { - solana_cluster - }; - - let account_keys = match solana_cluster { - Cluster::Devnet | Cluster::Localnet | Cluster::Mainnet => { - let client = RpcClient::new_with_timeout(&rpc_url, Duration::from_secs(300)); - let (creator, _) = find_candy_machine_creator_pda(&candy_machine_id); - let creator = bs58::encode(creator).into_string(); - get_cm_creator_metadata_accounts(&client, &creator, 0)? - } - _ => { - return Err(anyhow!( - "Cluster being used is unsupported for this command." - )) - } - }; - - if account_keys.is_empty() { - pb.finish_with_message(format!("{}", style("No NFTs found.").green().bold())); - return Err(anyhow!(format!( - "No NFTs found for candy machine id {candy_machine_id}.", - ))); - } else { - pb.finish_with_message(format!("Found {:?} accounts", account_keys.len() as u64)); - println!( - "\n{} {}Signing mint accounts", - style("[3/3]").bold().dim(), - SIGNING_EMOJI - ); - } - - let pb = progress_bar_with_style(account_keys.len() as u64); - - let semaphore = Arc::new(Semaphore::new(100)); - let mut join_handles = Vec::new(); - for account in account_keys { - let permit = Arc::clone(&semaphore).acquire_owned().await.unwrap(); - let config = sugar_config.clone(); - let pb = pb.clone(); - - join_handles.push(tokio::spawn(async move { - let _permit = permit; - sign(Arc::clone(&config), account).await.ok(); - pb.inc(1); - })); - } - - for handle in join_handles { - handle.await.map_err(|err| errors.push(err)).ok(); - } - - if !errors.is_empty() { - pb.abandon_with_message(format!("{}", style("Signing command failed ").red().bold())); - return Err(anyhow!("Not all NFTs were signed.".to_string())); - } else { - pb.finish_with_message(format!( - "{}", - style("All NFTs signed successfully.").green().bold() - )); - } - } - - Ok(()) -} - -async fn sign(config: Arc, metadata: Pubkey) -> Result<(), Error> { - let client = setup_client(&config)?; - let program = client.program(CANDY_MACHINE_ID); - - let recent_blockhash = program.rpc().get_latest_blockhash()?; - - let ix = sign_metadata(METAPLEX_PROGRAM_ID, metadata, config.keypair.pubkey()); - let tx = Transaction::new_signed_with_payer( - &[ix], - Some(&config.keypair.pubkey()), - &[&config.keypair], - recent_blockhash, - ); - - // Send tx with retries. - retry( - Exponential::from_millis_with_factor(250, 2.0).take(3), - || program.rpc().send_and_confirm_transaction(&tx), - )?; - - Ok(()) -} diff --git a/src/update/mod.rs b/src/update/mod.rs index 40f1e748..6dc80e85 100644 --- a/src/update/mod.rs +++ b/src/update/mod.rs @@ -1,5 +1,3 @@ pub mod process; -pub mod set_token_standard; pub use process::*; -pub use set_token_standard::*; diff --git a/src/update/process.rs b/src/update/process.rs index eee93c71..8d8db6e7 100644 --- a/src/update/process.rs +++ b/src/update/process.rs @@ -3,7 +3,7 @@ use std::str::FromStr; use anchor_client::solana_sdk::{compute_budget::ComputeBudgetInstruction, pubkey::Pubkey}; use anyhow::Result; use console::style; -use mpl_candy_machine_core::{ +use mpl_core_candy_machine_core::{ accounts as nft_accounts, instruction as nft_instruction, CandyMachineData, }; @@ -74,7 +74,7 @@ pub fn process_update(args: UpdateArgs) -> Result<()> { COMPUTER_EMOJI ); - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let priority_fee = ComputeBudgetInstruction::set_compute_unit_price(args.priority_fee); let builder = program @@ -135,19 +135,9 @@ fn create_candy_machine_data( ) -> Result { let hidden_settings = config.hidden_settings.as_ref().map(|s| s.to_candy_format()); - let creators = config - .creators - .clone() - .into_iter() - .map(|c| c.to_candy_format()) - .collect::>>()?; - let data = CandyMachineData { - symbol: config.symbol.clone(), - seller_fee_basis_points: config.seller_fee_basis_points, max_supply: 0, is_mutable: config.is_mutable, - creators, hidden_settings, config_line_settings: candy_machine.config_line_settings.clone(), items_available: config.number, diff --git a/src/update/set_token_standard.rs b/src/update/set_token_standard.rs deleted file mode 100644 index 1cf3ca01..00000000 --- a/src/update/set_token_standard.rs +++ /dev/null @@ -1,156 +0,0 @@ -use std::str::FromStr; - -use anchor_client::solana_sdk::{compute_budget::ComputeBudgetInstruction, pubkey::Pubkey}; -use anyhow::Result; -use console::style; -use mpl_candy_machine_core::{accounts::SetTokenStandard, AccountVersion}; -use mpl_token_metadata::{ - instruction::MetadataDelegateRole, - pda::{find_collection_authority_account, find_metadata_delegate_record_account}, -}; - -use crate::{ - cache::load_cache, - candy_machine::{get_candy_machine_state, CANDY_MACHINE_ID}, - common::*, - config::TokenStandard, - pdas::{find_candy_machine_creator_pda, find_metadata_pda, get_metadata_pda}, - utils::*, -}; - -pub struct SetTokenStandardArgs { - pub keypair: Option, - pub rpc_url: Option, - pub cache: String, - pub token_standard: Option, - pub candy_machine: Option, - pub rule_set: Option, - pub priority_fee: u64, -} - -pub fn process_set_token_stardard(args: SetTokenStandardArgs) -> Result<()> { - // validate that we got the required input - if args.token_standard.is_none() && args.rule_set.is_none() { - return Err(anyhow!( - "You need to specify a token standard and/or rule set." - )); - } - - println!("[1/2] {}Loading candy machine", LOOKING_GLASS_EMOJI); - - // the candy machine id specified takes precedence over the one from the cache - - let candy_machine_id = if let Some(candy_machine) = args.candy_machine { - candy_machine - } else { - let cache = load_cache(&args.cache, false)?; - cache.program.candy_machine - }; - - if candy_machine_id.is_empty() { - return Err(anyhow!("Missing candy guard id.")); - } - - let candy_machine_id = match Pubkey::from_str(&candy_machine_id) { - Ok(candy_machine_id) => candy_machine_id, - Err(_) => { - let error = anyhow!("Failed to parse candy machine id: {}", candy_machine_id); - error!("{:?}", error); - return Err(error); - } - }; - - let sugar_config = sugar_setup(args.keypair, args.rpc_url)?; - let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); - - let pb = spinner_with_style(); - pb.set_message("Connecting..."); - - let candy_machine_state = get_candy_machine_state(&sugar_config, &candy_machine_id)?; - - pb.finish_with_message("Done"); - - let message = if args.token_standard.is_some() { - if args.rule_set.is_some() { - "token standard and rule set" - } else { - "token standard" - } - } else { - "rule set" - }; - - println!("\n[2/2] {}Setting {}", WITHDRAW_EMOJI, message); - - let pb = spinner_with_style(); - pb.set_message("Connecting..."); - - let (authority_pda, _) = find_candy_machine_creator_pda(&candy_machine_id); - let collection_mint = candy_machine_state.collection_mint; - let collection_metadata = find_metadata_pda(&collection_mint); - let (_, collection_metadata_pda) = - get_metadata_pda(&candy_machine_state.collection_mint, &program)?; - let collection_update_authority = collection_metadata_pda.update_authority; - - let collection_authority_record = if matches!(candy_machine_state.version, AccountVersion::V1) { - Some(find_collection_authority_account(&collection_mint, &authority_pda).0) - } else { - None - }; - - let collection_delegate_record = find_metadata_delegate_record_account( - &collection_mint, - MetadataDelegateRole::Collection, - &collection_update_authority, - &authority_pda, - ) - .0; - - // either uses the specified token standard or the existing one, for the case - // where only the rule set will be set - let token_standard = if let Some(token_standard) = args.token_standard { - >::into( - token_standard, - ) as u8 - } else { - candy_machine_state.token_standard - }; - - let payer = sugar_config.keypair; - - let priority_fee = ComputeBudgetInstruction::set_compute_unit_price(args.priority_fee); - - let tx = program - .request() - .instruction(priority_fee) - .accounts(SetTokenStandard { - candy_machine: candy_machine_id, - authority_pda, - authority: payer.pubkey(), - payer: payer.pubkey(), - collection_metadata, - collection_mint, - collection_update_authority, - collection_authority_record, - collection_delegate_record, - rule_set: if let Some(rule_set) = args.rule_set { - Some(Pubkey::from_str(&rule_set)?) - } else { - None - }, - system_program: system_program::ID, - sysvar_instructions: sysvar::instructions::ID, - token_metadata_program: mpl_token_metadata::ID, - authorization_rules_program: None, - authorization_rules: None, - }) - .args(mpl_candy_machine_core::instruction::SetTokenStandard { token_standard }); - - let sig = tx.send()?; - - pb.finish_and_clear(); - println!("{} {}", style("Signature:").bold(), sig); - - Ok(()) -} diff --git a/src/upload/assets.rs b/src/upload/assets.rs index b361f0cc..51f6356f 100644 --- a/src/upload/assets.rs +++ b/src/upload/assets.rs @@ -355,7 +355,7 @@ pub fn get_updated_metadata( if animation_link.is_some() { // only updates the link if we have a new value - metadata.animation_url = animation_link.clone(); + metadata.animation_url.clone_from(animation_link); } Ok(serde_json::to_string(&metadata).unwrap()) diff --git a/src/upload/methods/bundlr.rs b/src/upload/methods/bundlr.rs index 4081c9d8..922b85a6 100644 --- a/src/upload/methods/bundlr.rs +++ b/src/upload/methods/bundlr.rs @@ -44,7 +44,7 @@ pub struct BundlrMethod { impl BundlrMethod { pub async fn new(sugar_config: &SugarConfig, _config_data: &ConfigData) -> Result { let client = setup_client(sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let solana_cluster: Cluster = get_cluster(program.rpc())?; let bundlr_node = match solana_cluster { @@ -287,7 +287,7 @@ impl Prepare for BundlrMethod { let rpc_client = { let client = setup_client(sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; program.rpc() }; diff --git a/src/upload/methods/shdw.rs b/src/upload/methods/shdw.rs index 32b51200..3ebf9c8a 100644 --- a/src/upload/methods/shdw.rs +++ b/src/upload/methods/shdw.rs @@ -60,7 +60,7 @@ impl SHDWMethod { pub async fn new(sugar_config: &SugarConfig, config_data: &ConfigData) -> Result { if let Some(pubkey) = &config_data.shdw_storage_account { let client = setup_client(sugar_config)?; - let program = client.program(SHADOW_DRIVE_PROGRAM_ID); + let program = client.program(SHADOW_DRIVE_PROGRAM_ID)?; let solana_cluster: Cluster = get_cluster(program.rpc())?; let endpoint = match solana_cluster { diff --git a/src/upload/process.rs b/src/upload/process.rs index 9944b6b4..32c530ce 100644 --- a/src/upload/process.rs +++ b/src/upload/process.rs @@ -55,7 +55,7 @@ pub async fn process_upload(args: UploadArgs) -> Result<()> { // creates/loads the cache let mut cache = load_cache(&args.cache, true)?; - if asset_pairs.get(&-1).is_none() { + if !asset_pairs.contains_key(&-1) { cache.items.remove("-1"); } @@ -123,27 +123,27 @@ pub async fn process_upload(args: UploadArgs) -> Result<()> { if image_changed { // triggers the image upload - item.image_hash = pair.image_hash.clone(); + item.image_hash.clone_from(&pair.image_hash); item.image_link = String::new(); indices.image.push(*index); } else if !existing_image.is_empty() { - item.image_hash = pair.image_hash.clone(); + item.image_hash.clone_from(&pair.image_hash); item.image_link = existing_image; } if animation_changed { // triggers the animation upload - item.animation_hash = pair.animation_hash.clone(); + item.animation_hash.clone_from(&pair.animation_hash); item.animation_link = None; indices.animation.push(*index); } else if !existing_animation.is_empty() { - item.animation_hash = pair.animation_hash.clone(); + item.animation_hash.clone_from(&pair.animation_hash); item.animation_link = Some(existing_animation); } if metadata_changed || image_changed || animation_changed { // triggers the metadata upload - item.metadata_hash = pair.metadata_hash.clone(); + item.metadata_hash.clone_from(&pair.metadata_hash); item.metadata_link = String::new(); item.on_chain = false; // we need to upload metadata only @@ -157,7 +157,7 @@ pub async fn process_upload(args: UploadArgs) -> Result<()> { if existing_image.is_empty() { indices.image.push(*index); } else { - item.image_hash = pair.image_hash.clone(); + item.image_hash.clone_from(&pair.image_hash); item.image_link = existing_image; } @@ -166,7 +166,7 @@ pub async fn process_upload(args: UploadArgs) -> Result<()> { if existing_animation.is_empty() { indices.animation.push(*index); } else { - item.animation_hash = pair.animation_hash.clone(); + item.animation_hash.clone_from(&pair.animation_hash); item.animation_link = Some(existing_animation); } } @@ -175,24 +175,12 @@ pub async fn process_upload(args: UploadArgs) -> Result<()> { cache.items.insert(index.to_string(), item); } } - // sanity check: verifies that both symbol and seller-fee-basis-points are the - // same as the ones in the config file + // sanity check: verifies that seller-fee-basis-points are the + // same as the one in the config file let f = File::open(Path::new(&pair.metadata))?; match serde_json::from_reader(f) { Ok(metadata) => { let metadata: Metadata = metadata; - // symbol check, but only if the asset actually has the value - if let Some(symbol) = metadata.symbol { - if config_data.symbol.ne(&symbol) { - return Err(UploadError::MismatchValue( - "symbol".to_string(), - pair.metadata.clone(), - config_data.symbol, - symbol, - ) - .into()); - } - } // seller-fee-basis-points check, but only if the asset actually has the value if let Some(seller_fee_basis_points) = metadata.seller_fee_basis_points { if config_data.seller_fee_basis_points != seller_fee_basis_points { diff --git a/src/utils.rs b/src/utils.rs index 72d9bd32..677ad1ea 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -3,7 +3,6 @@ use std::{ops::Deref, str::FromStr, thread::sleep, time::Duration}; pub use anchor_client::solana_sdk::hash::Hash; use anchor_client::{ solana_sdk::{ - account::Account, commitment_config::{CommitmentConfig, CommitmentLevel}, program_pack::{IsInitialized, Pack}, pubkey::Pubkey, @@ -14,7 +13,7 @@ pub use anyhow::{anyhow, Result}; use console::{style, Style}; use dialoguer::theme::ColorfulTheme; pub use indicatif::{ProgressBar, ProgressStyle}; -use mpl_token_metadata::ID as TOKEN_METADATA_PROGRAM_ID; +use mpl_core::accounts::BaseCollectionV1; use solana_account_decoder::UiAccountEncoding; use solana_client::{ rpc_client::RpcClient, @@ -160,73 +159,31 @@ pub fn f64_to_u64_safe(f: f64) -> Result { Ok(f.trunc() as u64) } -pub fn get_cm_creator_metadata_accounts( +pub fn get_cm_mint_accounts( client: &RpcClient, - creator: &str, - position: usize, + collection: &str, + // position: usize, ) -> Result> { - let accounts = get_cm_creator_accounts(client, creator, position)? - .into_iter() - .map(|(pubkey, _account)| pubkey) - .collect::>(); - - Ok(accounts) -} - -pub fn get_cm_creator_mint_accounts( - client: &RpcClient, - creator: &str, - position: usize, -) -> Result> { - let accounts = get_cm_creator_accounts(client, creator, position)? - .into_iter() - .map(|(_, account)| account.data[33..65].to_vec()) - .map(|data| { - Pubkey::from( - as std::convert::TryInto<[u8; 32]>>::try_into(data) - .expect("slice with incorrect length"), - ) - }) - .collect::>(); - - Ok(accounts) -} - -fn get_cm_creator_accounts( - client: &RpcClient, - creator: &str, - position: usize, -) -> Result> { - if position > 4 { - error!("CM Creator position cannot be greator than 4"); - std::process::exit(1); - } - let creator = Pubkey::from_str(creator)?; - - let creator_filter = RpcFilterType::Memcmp(Memcmp::new_base58_encoded( + // let accounts = get_cm_creator_accounts(client, creator, position)? + // .into_iter() + // .map(|(_, account)| account.data[33..65].to_vec()) + // .map(|data| { + // Pubkey::from( + // as std::convert::TryInto<[u8; 32]>>::try_into(data) + // .expect("slice with incorrect length"), + // ) + // }) + // .collect::>(); + + let collection_filter = RpcFilterType::Memcmp(Memcmp::new_base58_encoded( 1 + // key - 32 + // update auth - 32 + // mint - 4 + // name string length - MAX_NAME_LENGTH + // name - 4 + // uri string length - MAX_URI_LENGTH + // uri* - 4 + // symbol string length - MAX_SYMBOL_LENGTH + // symbol - 2 + // seller fee basis points - 1 + // whether or not there is a creators vec - 4 + // creators - position * // index for each creator - ( - 32 + // address - 1 + // verified - 1 // share - ), - creator.as_ref(), + 32 + // owner + 1, // UA discriminator + collection.as_ref(), )); let config = RpcProgramAccountsConfig { - filters: Some(vec![creator_filter]), + filters: Some(vec![collection_filter]), account_config: RpcAccountInfoConfig { encoding: Some(UiAccountEncoding::Base64), data_slice: None, @@ -238,7 +195,25 @@ fn get_cm_creator_accounts( with_context: None, }; - let results = client.get_program_accounts_with_config(&TOKEN_METADATA_PROGRAM_ID, config)?; + let results = client.get_program_accounts_with_config(&mpl_core::ID, config)?; - Ok(results) + Ok(results.into_iter().map(|(pubkey, _)| pubkey).collect()) +} + +pub fn get_base_collection + Clone>( + address: &Pubkey, + program: &Program, +) -> Result { + let collection_account = program + .rpc() + .get_account(address) + .map_err(|_| anyhow!("Couldn't find metadata account: {}", &address.to_string()))?; + + let collection = BaseCollectionV1::from_bytes(collection_account.data.as_slice()); + collection.map_err(|_| { + anyhow!( + "Failed to deserialize metadata account: {}", + &address.to_string() + ) + }) } diff --git a/src/validate/format.rs b/src/validate/format.rs index e20dfdff..93d391f0 100644 --- a/src/validate/format.rs +++ b/src/validate/format.rs @@ -25,16 +25,10 @@ pub struct Metadata { impl Metadata { pub fn validate(&mut self) -> Result<(), ValidateParserError> { - parser::check_name(&self.name)?; - parser::check_url(&self.image)?; - // If users are using the old format, we do validation on those values. if let Some(sfbp) = &self.seller_fee_basis_points { parser::check_seller_fee_basis_points(*sfbp)?; } - if let Some(symbol) = &self.symbol { - parser::check_symbol(symbol)?; - } if let Some(creators) = &self.properties.creators { parser::check_creators_shares(creators)?; @@ -60,14 +54,6 @@ impl Metadata { .expect("unreachable, should never throw"), )?; - if let Some(animation_url) = &self.animation_url { - parser::check_url(animation_url)?; - } - - if let Some(external_url) = &self.external_url { - parser::check_url(external_url)?; - } - Ok(()) } } diff --git a/src/validate/parser.rs b/src/validate/parser.rs index 0b2c738d..cf5fc985 100644 --- a/src/validate/parser.rs +++ b/src/validate/parser.rs @@ -1,34 +1,12 @@ use std::str::FromStr; use anchor_lang::prelude::Pubkey; -pub use mpl_token_metadata::state::{MAX_NAME_LENGTH, MAX_SYMBOL_LENGTH, MAX_URI_LENGTH}; use crate::{ common::*, validate::{errors::ValidateParserError, Creator}, }; -pub fn check_name(name: &str) -> Result<(), ValidateParserError> { - if name.len() > MAX_NAME_LENGTH { - return Err(ValidateParserError::NameTooLong); - } - Ok(()) -} - -pub fn check_symbol(symbol: &str) -> Result<(), ValidateParserError> { - if symbol.len() > MAX_SYMBOL_LENGTH { - return Err(ValidateParserError::SymbolTooLong); - } - Ok(()) -} - -pub fn check_url(url: &str) -> Result<(), ValidateParserError> { - if url.len() > MAX_URI_LENGTH { - return Err(ValidateParserError::UrlTooLong); - } - Ok(()) -} - pub fn check_seller_fee_basis_points( seller_fee_basis_points: u16, ) -> Result<(), ValidateParserError> { diff --git a/src/verify/process.rs b/src/verify/process.rs index 27011b74..e1d34e33 100644 --- a/src/verify/process.rs +++ b/src/verify/process.rs @@ -1,10 +1,8 @@ use std::{thread, time::Duration}; use anchor_lang::AccountDeserialize; -use borsh::BorshDeserialize; use console::style; -use mpl_candy_machine_core::{constants::HIDDEN_SECTION, CandyMachine}; -use mpl_token_metadata::state::Metadata; +use mpl_core_candy_machine_core::{constants::HIDDEN_SECTION, CandyMachine}; use crate::{ cache::*, @@ -12,7 +10,6 @@ use crate::{ common::*, config::Cluster, constants::{CANDY_EMOJI, PAPER_EMOJI}, - pdas::find_metadata_pda, utils::*, verify::VerifyError, }; @@ -69,7 +66,7 @@ pub fn process_verify(args: VerifyArgs) -> Result<()> { }; let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let data = match program.rpc().get_account_data(&candy_machine_pubkey) { Ok(account_data) => account_data, @@ -182,13 +179,11 @@ pub fn process_verify(args: VerifyArgs) -> Result<()> { }; let collection_item = cache.items.get_mut("-1"); - let collection_metadata = find_metadata_pda(&candy_machine.collection_mint); - let data = program.rpc().get_account_data(&collection_metadata)?; - let metadata: Metadata = BorshDeserialize::deserialize(&mut data.as_slice())?; + // let collection = get_base_collection(&candy_machine.collection_mint, &program)?; - if metadata.mint.to_string() != collection_mint_cache { + if candy_machine.collection_mint.to_string() != collection_mint_cache { println!("\nInvalid collection state found"); - cache.program.collection_mint = metadata.mint.to_string(); + cache.program.collection_mint = candy_machine.collection_mint.to_string(); if let Some(collection_item) = collection_item { collection_item.on_chain = false; } @@ -197,7 +192,7 @@ pub fn process_verify(args: VerifyArgs) -> Result<()> { return Err(anyhow!( "Collection mint in cache {} doesn't match on chain collection mint {}!", collection_mint_cache, - metadata.mint.to_string() + candy_machine.collection_mint.to_string() )); } else if collection_needs_deploy { println!("\nInvalid collection state found - re-run `deploy`."); diff --git a/src/withdraw/process.rs b/src/withdraw/process.rs index 4a84c89d..5b1de0fa 100644 --- a/src/withdraw/process.rs +++ b/src/withdraw/process.rs @@ -14,7 +14,7 @@ pub use anchor_client::{ }; use console::{style, Style}; use dialoguer::{theme::ColorfulTheme, Confirm}; -use mpl_candy_machine_core::{accounts as nft_accounts, instruction as nft_instruction}; +use mpl_core_candy_machine_core::{accounts as nft_accounts, instruction as nft_instruction}; use solana_account_decoder::UiAccountEncoding; use solana_client::{ rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig}, @@ -219,7 +219,7 @@ fn setup_withdraw( ) -> Result<(Program>, Pubkey, Pubkey)> { let sugar_config = sugar_setup(keypair, rpc_url)?; let client = setup_client(&sugar_config)?; - let program = client.program(CANDY_MACHINE_ID); + let program = client.program(CANDY_MACHINE_ID)?; let payer = program.payer(); let authority = if let Some(authority_str) = authority_opt { Pubkey::from_str(&authority_str)?