diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..86ba56d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/binaries \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..878d251 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,176 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "libc" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2f96d100e1cf1929e7719b7edb3b90ab5298072638fccd77be9ce942ecdfce" + +[[package]] +name = "phf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9fc3db1018c4b59d7d582a739436478b6035138b6aecbce989fc91c3e98409f" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741" + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core", +] + +[[package]] +name = "siphasher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" + +[[package]] +name = "syn" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wtf-is" +version = "0.1.0" +dependencies = [ + "phf", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..ae8cee7 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "wtf-is" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +phf = { version = "0.10", features = ["macros"] } \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..40c212c --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# WTF Is + +I was tired of looking up Metaplex Token Metadata program errors. + +```bash +wtf-is +``` + +Example: + +```bash +$ wtf-is 37 +> 0x37: CannotUnverifyAnotherCreator: You cannot unilaterally unverify another creator +``` + diff --git a/build-linux.sh b/build-linux.sh new file mode 100755 index 0000000..a9cb55b --- /dev/null +++ b/build-linux.sh @@ -0,0 +1,6 @@ +name=$(awk -F'[ ="]+' '$1 == "name" { print $2 }' Cargo.toml) +version=$(awk -F'[ ="]+' '$1 == "version" { print $2 }' Cargo.toml) +cargo build --release +cp ./target/release/$name ./binaries/$name-$version-x86_64-unknown-linux-gnu +cargo build --release --target x86_64-unknown-linux-musl +cp ./target/x86_64-unknown-linux-musl/release/$name ./binaries/$name-$version-x86_64-unknown-linux-musl \ No newline at end of file diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..2b4ae67 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,77 @@ +use phf::phf_map; + +pub static ERRORS: phf::Map<&'static str, &'static str> = phf_map! { +"0" => "InstructionUnpackError: Failed to unpack instruction data", +"1" => "InstructionPackError: Failed to pack instruction data", +"2" => "NotRentExempt: Lamport balance below rent-exempt threshold", +"3" => "AlreadyInitialized: Already initialized", +"4" => "Uninitialized: Uninitialized", +"5" => "InvalidMetadataKey: Metadata's key must match seed of ['metadata', program id, mint] provided", +"6" => "InvalidEditionKey: Edition's key must match seed of ['metadata', program id, name, 'edition'] provided", +"7" => "UpdateAuthorityIncorrect: Update Authority given does not match", +"8" => "UpdateAuthorityIsNotSigner: Update Authority needs to be signer to update metadata", +"9" => "NotMintAuthority: You must be the mint authority and signer on this transaction", +"A" => "InvalidMintAuthority: Mint authority provided does not match the authority on the mint", +"B" => "NameTooLong: Name too long", +"C" => "SymbolTooLong: Symbol too long", +"D" => "UriTooLong: URI too long", +"E" => "UpdateAuthorityMustBeEqualToMetadataAuthorityAndSigner: Update authority must be equivalent to the metadata's authority and also signer of this transaction", +"F" => "MintMismatch: Mint given does not match mint on Metadata", +"10" => "EditionsMustHaveExactlyOneToken: Editions must have exactly one token", +"11" => "MaxEditionsMintedAlready: Maximum editions printed already", +"12" => "TokenMintToFailed: Token mint to failed", +"13" => "MasterRecordMismatch: The master edition record passed must match the master record on the edition given", +"14" => "DestinationMintMismatch: The destination account does not have the right mint", +"15" => "EditionAlreadyMinted: An edition can only mint one of its kind!", +"16" => "PrintingMintDecimalsShouldBeZero: Printing mint decimals should be zero", +"17" => "OneTimePrintingAuthorizationMintDecimalsShouldBeZero: OneTimePrintingAuthorization mint decimals should be zero", +"18" => "EditionMintDecimalsShouldBeZero: EditionMintDecimalsShouldBeZero", +"19" => "TokenBurnFailed: Token burn failed", +"1A" => "TokenAccountOneTimeAuthMintMismatch: The One Time authorization mint does not match that on the token account!", +"1B" => "DerivedKeyInvalid: Derived key invalid", +"1C" => "PrintingMintMismatch: The Printing mint does not match that on the master edition!", +"1D" => "OneTimePrintingAuthMintMismatch: The One Time Printing Auth mint does not match that on the master edition!", +"1E" => "TokenAccountMintMismatch: The mint of the token account does not match the Printing mint!", +"1F" => "TokenAccountMintMismatchV2: The mint of the token account does not match the master metadata mint!", +"20" => "NotEnoughTokens: Not enough tokens to mint a limited edition", +"21" => "PrintingMintAuthorizationAccountMismatch: The mint on your authorization token holding account does not match your Printing mint!", +"22" => "AuthorizationTokenAccountOwnerMismatch: The authorization token account has a different owner than the update authority for the master edition!", +"23" => "Disabled: This feature is currently disabled.", +"24" => "CreatorsTooLong: Creators list too long", +"25" => "CreatorsMustBeAtleastOne: Creators must be at least one if set", +"26" => "MustBeOneOfCreators: If using a creators array, you must be one of the creators listed", +"27" => "NoCreatorsPresentOnMetadata: This metadata does not have creators", +"28" => "CreatorNotFound: This creator address was not found", +"29" => "InvalidBasisPoints: Basis points cannot be more than 10000", +"2A" => "PrimarySaleCanOnlyBeFlippedToTrue: Primary sale can only be flipped to true and is immutable", +"2B" => "OwnerMismatch: Owner does not match that on the account given", +"2C" => "NoBalanceInAccountForAuthorization: This account has no tokens to be used for authorization", +"2D" => "ShareTotalMustBe100: Share total must equal 100 for creator array", +"2E" => "ReservationExists: This reservation list already exists!", +"2F" => "ReservationDoesNotExist: This reservation list does not exist!", +"30" => "ReservationNotSet: This reservation list exists but was never set with reservations", +"31" => "ReservationAlreadyMade: This reservation list has already been set!", +"32" => "BeyondMaxAddressSize: Provided more addresses than max allowed in single reservation", +"33" => "NumericalOverflowError: NumericalOverflowError", +"34" => "ReservationBreachesMaximumSupply: This reservation would go beyond the maximum supply of the master edition!", +"35" => "AddressNotInReservation: Address not in reservation!", +"36" => "CannotVerifyAnotherCreator: You cannot unilaterally verify another creator, they must sign", +"37" => "CannotUnverifyAnotherCreator: You cannot unilaterally unverify another creator", +"38" => "SpotMismatch: In initial reservation setting, spots remaining should equal total spots", +"39" => "IncorrectOwner: Incorrect account owner", +"3A" => "PrintingWouldBreachMaximumSupply: printing these tokens would breach the maximum supply limit of the master edition", +"3B" => "DataIsImmutable: Data is immutable", +"3C" => "DuplicateCreatorAddress: No duplicate creator addresses", +"3D" => "ReservationSpotsRemainingShouldMatchTotalSpotsAtStart: Reservation spots remaining should match total spots when first being created", +"3E" => "InvalidTokenProgram: Invalid token program", +"3F" => "DataTypeMismatch: Data type mismatch", +"40" => "BeyondAlottedAddressSize: Beyond alotted address size in reservation!", +"41" => "ReservationNotComplete: The reservation has only been partially alotted", +"42" => "TriedToReplaceAnExistingReservation: You cannot splice over an existing reservation!", +"43" => "InvalidOperation: Invalid operation", +"44" => "InvalidOwner: Invalid Owner", +"45" => "PrintingMintSupplyMustBeZeroForConversion: Printing mint supply must be zero for conversion", +"46" => "OneTimeAuthMintSupplyMustBeZeroForConversion: One Time Auth mint supply must be zero for conversion", +"47" => "InvalidEditionIndex: You tried to insert one edition too many into an edition mark pda", +"48" => "ReservationArrayShouldBeSizeOne: In the legacy system the reservation needs to be of size one for cpu limit reasons", +}; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..105a9fa --- /dev/null +++ b/src/main.rs @@ -0,0 +1,29 @@ +use std::env::args; + +mod errors; + +fn main() { + let hex_code = args().skip(1).next(); + + match hex_code { + Some(code) => { + let code = code.to_uppercase(); + let message = parse(&code); + println!("0x{}: {}", code, message); + } + None => { + println!("No hex code provided!"); + std::process::exit(1); + } + } +} + +pub fn parse(hex_code: &str) -> &str { + match errors::ERRORS.get(hex_code).cloned() { + Some(e) => return e, + None => { + println!("No match found for that code!"); + std::process::exit(1); + } + } +}