From 45531de8bcb770688abf2dc90b41a2de62ebe71d Mon Sep 17 00:00:00 2001 From: Perelyn-sama Date: Tue, 22 Oct 2024 15:07:46 +0100 Subject: [PATCH 1/5] add pda mint authority steel example --- tokens/pda-mint-authority/steel/.gitignore | 2 + tokens/pda-mint-authority/steel/Cargo.toml | 24 ++++ tokens/pda-mint-authority/steel/README.md | 22 ++++ .../pda-mint-authority/steel/api/Cargo.toml | 14 +++ .../steel/api/src/consts.rs | 23 ++++ .../pda-mint-authority/steel/api/src/error.rs | 10 ++ .../steel/api/src/instruction.rs | 27 +++++ .../pda-mint-authority/steel/api/src/lib.rs | 18 +++ .../pda-mint-authority/steel/api/src/sdk.rs | 78 ++++++++++++ .../steel/api/src/state/mint_authority.rs | 11 ++ .../steel/api/src/state/mod.rs | 18 +++ .../steel/program/Cargo.toml | 21 ++++ .../steel/program/src/create.rs | 111 ++++++++++++++++++ .../steel/program/src/lib.rs | 25 ++++ .../steel/program/src/mint.rs | 53 +++++++++ .../steel/program/tests/test.rs | 46 ++++++++ 16 files changed, 503 insertions(+) create mode 100644 tokens/pda-mint-authority/steel/.gitignore create mode 100644 tokens/pda-mint-authority/steel/Cargo.toml create mode 100644 tokens/pda-mint-authority/steel/README.md create mode 100644 tokens/pda-mint-authority/steel/api/Cargo.toml create mode 100644 tokens/pda-mint-authority/steel/api/src/consts.rs create mode 100644 tokens/pda-mint-authority/steel/api/src/error.rs create mode 100644 tokens/pda-mint-authority/steel/api/src/instruction.rs create mode 100644 tokens/pda-mint-authority/steel/api/src/lib.rs create mode 100644 tokens/pda-mint-authority/steel/api/src/sdk.rs create mode 100644 tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs create mode 100644 tokens/pda-mint-authority/steel/api/src/state/mod.rs create mode 100644 tokens/pda-mint-authority/steel/program/Cargo.toml create mode 100644 tokens/pda-mint-authority/steel/program/src/create.rs create mode 100644 tokens/pda-mint-authority/steel/program/src/lib.rs create mode 100644 tokens/pda-mint-authority/steel/program/src/mint.rs create mode 100644 tokens/pda-mint-authority/steel/program/tests/test.rs diff --git a/tokens/pda-mint-authority/steel/.gitignore b/tokens/pda-mint-authority/steel/.gitignore new file mode 100644 index 000000000..052739dbc --- /dev/null +++ b/tokens/pda-mint-authority/steel/.gitignore @@ -0,0 +1,2 @@ +target +test-ledger diff --git a/tokens/pda-mint-authority/steel/Cargo.toml b/tokens/pda-mint-authority/steel/Cargo.toml new file mode 100644 index 000000000..633f3ac6e --- /dev/null +++ b/tokens/pda-mint-authority/steel/Cargo.toml @@ -0,0 +1,24 @@ +[workspace] +resolver = "2" +members = ["api", "program"] + +[workspace.package] +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" +homepage = "" +documentation = "" +respository = "" +readme = "./README.md" +keywords = ["solana"] + +[workspace.dependencies] +steel-api = { path = "./api", version = "0.1.0" } +bytemuck = "1.14" +num_enum = "0.7" +solana-program = "1.18" +steel = { version = "1.3", features = ["spl"] } +thiserror = "1.0" +mpl-token-metadata = { version = "4.1.2" } +spl-token = "^4" +const-crypto = "0.1.0" diff --git a/tokens/pda-mint-authority/steel/README.md b/tokens/pda-mint-authority/steel/README.md new file mode 100644 index 000000000..4f4fe2a54 --- /dev/null +++ b/tokens/pda-mint-authority/steel/README.md @@ -0,0 +1,22 @@ +# Steel + +**Steel** is a ... + +## API +- [`Consts`](api/src/consts.rs) – Program constants. +- [`Error`](api/src/error.rs) – Custom program errors. +- [`Event`](api/src/event.rs) – Custom program events. +- [`Instruction`](api/src/instruction.rs) – Declared instructions. + +## Instructions +- [`Hello`](program/src/hello.rs) – Hello ... + +## State +- [`User`](api/src/state/user.rs) – User ... + +## Tests + +To run the test suit, use the Solana toolchain: +``` +cargo test-sbf +``` diff --git a/tokens/pda-mint-authority/steel/api/Cargo.toml b/tokens/pda-mint-authority/steel/api/Cargo.toml new file mode 100644 index 000000000..d69375962 --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "steel-api" +version = "0.1.0" +edition = "2021" + +[dependencies] +bytemuck.workspace = true +num_enum.workspace = true +solana-program.workspace = true +steel.workspace = true +thiserror.workspace = true +spl-token.workspace = true +mpl-token-metadata.workspace = true +const-crypto.workspace = true diff --git a/tokens/pda-mint-authority/steel/api/src/consts.rs b/tokens/pda-mint-authority/steel/api/src/consts.rs new file mode 100644 index 000000000..49ae6daad --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/src/consts.rs @@ -0,0 +1,23 @@ +use const_crypto::ed25519; +use solana_program::pubkey::Pubkey; + +/// Program id for const pda derivations +const PROGRAM_ID: [u8; 32] = unsafe { *(&crate::id() as *const Pubkey as *const [u8; 32]) }; + +/// The seed of the mint authority account PDA. +pub const MINT_AUTHORITY: &[u8] = b"mint_authority"; + +/// The seed of the mint account PDA. +pub const MINT: &[u8] = b"mint"; + +/// Noise for deriving the mint pda +pub const MINT_NOISE: [u8; 16] = [ + 89, 157, 88, 232, 243, 249, 197, 132, 199, 49, 19, 234, 91, 94, 150, 41, +]; + +/// The seed of the metadata account PDA. +pub const METADATA: &[u8] = b"metadata"; + +/// The bump of the mint authority account, for cpis. +pub const MINT_AUTHORITY_BUMP: u8 = + ed25519::derive_program_address(&[MINT_AUTHORITY], &PROGRAM_ID).1; diff --git a/tokens/pda-mint-authority/steel/api/src/error.rs b/tokens/pda-mint-authority/steel/api/src/error.rs new file mode 100644 index 000000000..96e84da4d --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/src/error.rs @@ -0,0 +1,10 @@ +use steel::*; + +#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] +#[repr(u32)] +pub enum SteelError { + #[error("This is a dummy error")] + Dummy = 0, +} + +error!(SteelError); diff --git a/tokens/pda-mint-authority/steel/api/src/instruction.rs b/tokens/pda-mint-authority/steel/api/src/instruction.rs new file mode 100644 index 000000000..9f09492d7 --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/src/instruction.rs @@ -0,0 +1,27 @@ +use steel::*; + +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] +pub enum SteelInstruction { + Create = 0, + Mint = 1, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Create { + pub token_name: [u8; 32], + pub token_symbol: [u8; 8], + pub token_uri: [u8; 64], + pub mint_authority_bump: u8, + pub mint_bump: u8, +} + +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Mint { + pub amount: [u8; 8], +} + +instruction!(SteelInstruction, Create); +instruction!(SteelInstruction, Mint); diff --git a/tokens/pda-mint-authority/steel/api/src/lib.rs b/tokens/pda-mint-authority/steel/api/src/lib.rs new file mode 100644 index 000000000..aed2ed84f --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/src/lib.rs @@ -0,0 +1,18 @@ +pub mod consts; +pub mod error; +pub mod instruction; +pub mod sdk; +pub mod state; + +pub mod prelude { + pub use crate::consts::*; + pub use crate::error::*; + pub use crate::instruction::*; + pub use crate::sdk::*; + pub use crate::state::*; +} + +use steel::*; + +// TODO Set program id +declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35"); diff --git a/tokens/pda-mint-authority/steel/api/src/sdk.rs b/tokens/pda-mint-authority/steel/api/src/sdk.rs new file mode 100644 index 000000000..aec6fadca --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/src/sdk.rs @@ -0,0 +1,78 @@ +use steel::*; + +use crate::prelude::*; + +pub fn create( + payer: Pubkey, + token_name: String, + token_symbol: String, + token_uri: String, +) -> Instruction { + let token_name_bytes: [u8; 32] = token_name + .as_bytes() + .try_into() + .expect("String wrong length, expected 32 bytes"); + let token_symbol_bytes: [u8; 8] = token_symbol + .as_bytes() + .try_into() + .expect("String wrong length, expected 32 bytes"); + let token_uri_bytes: [u8; 64] = token_uri + .as_bytes() + .try_into() + .expect("String wrong length, expected 32 bytes"); + + let mint_pda = Pubkey::find_program_address(&[MINT, MINT_NOISE.as_slice()], &crate::ID); + let metadata_pda = Pubkey::find_program_address( + &[ + METADATA, + mpl_token_metadata::ID.as_ref(), + mint_pda.0.as_ref(), + ], + &mpl_token_metadata::ID, + ); + let mint_authority_pda = mint_authority_pda(); + + Instruction { + program_id: crate::ID, + accounts: vec![ + AccountMeta::new(payer, true), + AccountMeta::new(mint_pda.0, false), + AccountMeta::new(mint_authority_pda.0, false), + AccountMeta::new(metadata_pda.0, false), + AccountMeta::new_readonly(system_program::ID, false), + AccountMeta::new_readonly(spl_token::ID, false), + AccountMeta::new_readonly(mpl_token_metadata::ID, false), + AccountMeta::new_readonly(sysvar::rent::ID, false), + ], + data: Create { + token_name: token_name_bytes, + token_symbol: token_symbol_bytes, + token_uri: token_uri_bytes, + mint_authority_bump: mint_authority_pda.1, + mint_bump: mint_pda.1, + } + .to_bytes(), + } +} +pub fn mint( + signer: Pubkey, + mint: Pubkey, + to: Pubkey, + authority: Pubkey, + amount: u64, +) -> Instruction { + Instruction { + program_id: crate::ID, + accounts: vec![ + AccountMeta::new(signer, true), + AccountMeta::new(mint, false), + AccountMeta::new(to, false), + AccountMeta::new(authority, false), + AccountMeta::new_readonly(spl_token::ID, false), + ], + data: Mint { + amount: amount.to_le_bytes(), + } + .to_bytes(), + } +} diff --git a/tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs b/tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs new file mode 100644 index 000000000..8d8bbf9f0 --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs @@ -0,0 +1,11 @@ +use steel::*; + +use super::SteelAccount; + +#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] +pub struct MintAuthorityPda { + bump: u8, +} + +account!(SteelAccount, MintAuthorityPda); diff --git a/tokens/pda-mint-authority/steel/api/src/state/mod.rs b/tokens/pda-mint-authority/steel/api/src/state/mod.rs new file mode 100644 index 000000000..e3c9bdca3 --- /dev/null +++ b/tokens/pda-mint-authority/steel/api/src/state/mod.rs @@ -0,0 +1,18 @@ +mod mint_authority; + +pub use mint_authority::*; + +use steel::*; + +use crate::consts::*; + +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] +pub enum SteelAccount { + MintAuthorityPda = 0, +} + +/// Fetch PDA of the counter account. +pub fn mint_authority_pda() -> (Pubkey, u8) { + Pubkey::find_program_address(&[MINT_AUTHORITY], &crate::id()) +} diff --git a/tokens/pda-mint-authority/steel/program/Cargo.toml b/tokens/pda-mint-authority/steel/program/Cargo.toml new file mode 100644 index 000000000..0c8c7bd98 --- /dev/null +++ b/tokens/pda-mint-authority/steel/program/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "steel-program" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "lib"] + +[dependencies] +steel-api.workspace = true +solana-program.workspace = true +steel.workspace = true +spl-token.workspace = true +mpl-token-metadata.workspace = true + +[dev-dependencies] +bs64 = "0.1.2" +rand = "0.8.5" +solana-program-test = "1.18" +solana-sdk = "1.18" +tokio = { version = "1.35", features = ["full"] } diff --git a/tokens/pda-mint-authority/steel/program/src/create.rs b/tokens/pda-mint-authority/steel/program/src/create.rs new file mode 100644 index 000000000..136c6cd3b --- /dev/null +++ b/tokens/pda-mint-authority/steel/program/src/create.rs @@ -0,0 +1,111 @@ +use solana_program::msg; +use solana_program::program_pack::Pack; +use spl_token::state::Mint; +use steel::*; +use steel_api::prelude::*; + +pub fn process_create(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // parse args. + let args = Create::try_from_bytes(data)?; + let token_name = String::from_utf8(args.token_name.to_vec()).expect("Invalid UTF-8"); + let token_symbol = String::from_utf8(args.token_symbol.to_vec()).expect("Invalid UTF-8"); + let token_uri = String::from_utf8(args.token_uri.to_vec()).expect("Invalid UTF-8"); + + // Load accounts. + let [payer_info, mint_info, mint_authority_info, metadata_info, token_program, system_program, rent_sysvar, token_metadata_program] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + // validation + payer_info.is_signer()?; + mint_info.to_mint()?; + token_program.is_program(&spl_token::ID)?; + rent_sysvar.is_sysvar(&sysvar::rent::ID)?; + system_program.is_program(&system_program::ID)?; + token_program.is_program(&spl_token::ID)?; + token_metadata_program.is_program(&mpl_token_metadata::ID)?; + rent_sysvar.is_sysvar(&sysvar::rent::ID)?; + + mint_authority_info.is_empty()?.is_writable()?.has_seeds( + &[MINT_AUTHORITY], + args.mint_authority_bump, + &steel_api::ID, + )?; + + // Initialize mint authority. + create_account::( + mint_authority_info, + &steel_api::ID, + &[MINT_AUTHORITY, &[args.mint_authority_bump]], + system_program, + payer_info, + )?; + + // First create the account for the Mint + // + msg!("Creating mint account..."); + msg!("Mint: {}", mint_info.key); + allocate_account( + mint_info, + &spl_token::ID, + Mint::LEN, + &[MINT, MINT_NOISE.as_slice(), &[args.mint_bump]], + system_program, + payer_info, + )?; + + // Now initialize that account as a Mint (standard Mint) + // + msg!("Initializing mint account..."); + msg!("Mint: {}", mint_info.key); + solana_program::program::invoke( + &spl_token::instruction::initialize_mint( + &spl_token::ID, + mint_info.key, + mint_authority_info.key, + Some(mint_authority_info.key), + 9, // 9 Decimals for the default SPL Token standard, + )?, + &[ + token_program.clone(), + mint_info.clone(), + mint_authority_info.clone(), + rent_sysvar.clone(), + ], + )?; + + // Now create the account for that Mint's metadata + // + msg!("Creating metadata account..."); + msg!("Metadata account address: {}", metadata_info.key); + mpl_token_metadata::instructions::CreateMetadataAccountV3Cpi { + __program: token_metadata_program, + metadata: metadata_info, + mint: mint_info, + mint_authority: mint_authority_info, + payer: payer_info, + update_authority: (mint_authority_info, true), + system_program, + rent: Some(rent_sysvar), + __args: mpl_token_metadata::instructions::CreateMetadataAccountV3InstructionArgs { + data: mpl_token_metadata::types::DataV2 { + name: token_name, + symbol: token_symbol, + uri: token_uri, + seller_fee_basis_points: 0, + creators: None, + collection: None, + uses: None, + }, + is_mutable: true, + collection_details: None, + }, + } + .invoke_signed(&[&[MINT_AUTHORITY, &[args.mint_authority_bump]]])?; + + msg!("Token mint created successfully."); + + Ok(()) +} diff --git a/tokens/pda-mint-authority/steel/program/src/lib.rs b/tokens/pda-mint-authority/steel/program/src/lib.rs new file mode 100644 index 000000000..85b853681 --- /dev/null +++ b/tokens/pda-mint-authority/steel/program/src/lib.rs @@ -0,0 +1,25 @@ +mod create; +mod mint; + +pub use create::*; +pub use mint::*; + +use steel::*; +use steel_api::prelude::*; + +pub fn process_instruction( + program_id: &Pubkey, + accounts: &[AccountInfo], + data: &[u8], +) -> ProgramResult { + let (ix, data) = parse_instruction(&steel_api::ID, program_id, data)?; + + match ix { + SteelInstruction::Create => process_create(accounts, data)?, + SteelInstruction::Mint => process_mint(accounts, data)?, + } + + Ok(()) +} + +entrypoint!(process_instruction); diff --git a/tokens/pda-mint-authority/steel/program/src/mint.rs b/tokens/pda-mint-authority/steel/program/src/mint.rs new file mode 100644 index 000000000..8e37844ae --- /dev/null +++ b/tokens/pda-mint-authority/steel/program/src/mint.rs @@ -0,0 +1,53 @@ +use solana_program::msg; +use steel::*; +use steel_api::prelude::*; + +pub fn process_mint(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { + // parse args. + let args = Mint::try_from_bytes(data)?; + let amount = u64::from_le_bytes(args.amount); + + // Load accounts. + let [signer_info, mint_info, to_info, authority_info, token_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + msg!("Minting tokens to associated token account..."); + msg!("Mint: {:?}", mint_info); + msg!("Token Address: {:?}", &to_info); + + // validation + signer_info.is_signer()?; + mint_info.to_mint()?; + token_program.is_program(&spl_token::ID)?; + + to_info + .is_writable()? + .to_associated_token_account(signer_info.key, mint_info.key)? + .check(|t| t.owner == *signer_info.key)? + .check(|t| t.mint == *mint_info.key)?; + + token_program.is_program(&spl_token::ID)?; + + solana_program::program::invoke_signed( + &spl_token::instruction::mint_to( + &spl_token::id(), + mint_info.key, + to_info.key, + authority_info.key, + &[authority_info.key], + amount, + )?, + &[ + token_program.clone(), + mint_info.clone(), + to_info.clone(), + authority_info.clone(), + ], + &[&[MINT_AUTHORITY, &[MINT_AUTHORITY_BUMP]]], + )?; + + msg!("Token minted successfully."); + + Ok(()) +} diff --git a/tokens/pda-mint-authority/steel/program/tests/test.rs b/tokens/pda-mint-authority/steel/program/tests/test.rs new file mode 100644 index 000000000..c5bb50e1b --- /dev/null +++ b/tokens/pda-mint-authority/steel/program/tests/test.rs @@ -0,0 +1,46 @@ +use steel_api::prelude::*; +use solana_program::hash::Hash; +use solana_program_test::{processor, BanksClient, ProgramTest}; +use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction}; +use steel::*; + +async fn setup() -> (BanksClient, Keypair, Hash) { + let mut program_test = ProgramTest::new( + "steel", + steel_api::ID, + processor!(steel_program::process_instruction), + ); + program_test.prefer_bpf(true); + program_test.start().await +} + +#[tokio::test] +async fn run_test() { + // Setup test + let (mut banks, payer, blockhash) = setup().await; + + // Submit initialize transaction. + let ix = initialize(payer.pubkey()); + let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash); + let res = banks.process_transaction(tx).await; + assert!(res.is_ok()); + + // Verify counter was initialized. + let counter_address = counter_pda().0; + let counter_account = banks.get_account(counter_address).await.unwrap().unwrap(); + let counter = Counter::try_from_bytes(&counter_account.data).unwrap(); + assert_eq!(counter_account.owner, steel_api::ID); + assert_eq!(counter.value, 0); + + // Submit add transaction. + let ix = add(payer.pubkey(), 42); + let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash); + let res = banks.process_transaction(tx).await; + assert!(res.is_ok()); + + // Verify counter was incremented. + let counter_account = banks.get_account(counter_address).await.unwrap().unwrap(); + let counter = Counter::try_from_bytes(&counter_account.data).unwrap(); + assert_eq!(counter.value, 42); +} + From aa983841d426c426774137d9cd57e537164c9d53 Mon Sep 17 00:00:00 2001 From: Perelyn <64838956+Perelyn-sama@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:02:10 +0100 Subject: [PATCH 2/5] add steel tests --- tokens/pda-mint-authority/steel/Cargo.toml | 9 ++- .../pda-mint-authority/steel/api/Cargo.toml | 3 +- .../steel/api/src/consts.rs | 18 ----- .../pda-mint-authority/steel/api/src/error.rs | 10 --- .../steel/api/src/instruction.rs | 12 ++-- .../pda-mint-authority/steel/api/src/lib.rs | 6 +- .../pda-mint-authority/steel/api/src/sdk.rs | 68 +++++++++---------- .../steel/api/src/state/mint_authority.rs | 2 +- .../steel/api/src/state/mod.rs | 2 +- .../steel/program/Cargo.toml | 7 +- .../pda-mint-authority/steel/program/build.rs | 24 +++++++ .../steel/program/src/create.rs | 54 +++++++-------- .../steel/program/src/init.rs | 35 ++++++++++ .../steel/program/src/lib.rs | 7 +- .../steel/program/src/mint.rs | 53 ++++++++++----- .../steel/program/tests/test.rs | 63 +++++++++++------ 16 files changed, 226 insertions(+), 147 deletions(-) delete mode 100644 tokens/pda-mint-authority/steel/api/src/error.rs create mode 100644 tokens/pda-mint-authority/steel/program/build.rs create mode 100644 tokens/pda-mint-authority/steel/program/src/init.rs diff --git a/tokens/pda-mint-authority/steel/Cargo.toml b/tokens/pda-mint-authority/steel/Cargo.toml index 633f3ac6e..e0c03cf4d 100644 --- a/tokens/pda-mint-authority/steel/Cargo.toml +++ b/tokens/pda-mint-authority/steel/Cargo.toml @@ -8,17 +8,20 @@ edition = "2021" license = "Apache-2.0" homepage = "" documentation = "" -respository = "" +repository = "" readme = "./README.md" keywords = ["solana"] [workspace.dependencies] -steel-api = { path = "./api", version = "0.1.0" } +pda-mint-authority-api = { path = "./api", version = "0.1.0" } bytemuck = "1.14" num_enum = "0.7" solana-program = "1.18" -steel = { version = "1.3", features = ["spl"] } +steel = { version = "2.0", features = ["spl"] } thiserror = "1.0" mpl-token-metadata = { version = "4.1.2" } spl-token = "^4" const-crypto = "0.1.0" +spl-associated-token-account = { version = "^2.3", features = [ + "no-entrypoint", +] } diff --git a/tokens/pda-mint-authority/steel/api/Cargo.toml b/tokens/pda-mint-authority/steel/api/Cargo.toml index d69375962..d7cf41056 100644 --- a/tokens/pda-mint-authority/steel/api/Cargo.toml +++ b/tokens/pda-mint-authority/steel/api/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "steel-api" +name = "pda-mint-authority-api" version = "0.1.0" edition = "2021" @@ -12,3 +12,4 @@ thiserror.workspace = true spl-token.workspace = true mpl-token-metadata.workspace = true const-crypto.workspace = true +spl-associated-token-account.workspace = true diff --git a/tokens/pda-mint-authority/steel/api/src/consts.rs b/tokens/pda-mint-authority/steel/api/src/consts.rs index 49ae6daad..00688fe0e 100644 --- a/tokens/pda-mint-authority/steel/api/src/consts.rs +++ b/tokens/pda-mint-authority/steel/api/src/consts.rs @@ -1,23 +1,5 @@ -use const_crypto::ed25519; -use solana_program::pubkey::Pubkey; - -/// Program id for const pda derivations -const PROGRAM_ID: [u8; 32] = unsafe { *(&crate::id() as *const Pubkey as *const [u8; 32]) }; - /// The seed of the mint authority account PDA. pub const MINT_AUTHORITY: &[u8] = b"mint_authority"; -/// The seed of the mint account PDA. -pub const MINT: &[u8] = b"mint"; - -/// Noise for deriving the mint pda -pub const MINT_NOISE: [u8; 16] = [ - 89, 157, 88, 232, 243, 249, 197, 132, 199, 49, 19, 234, 91, 94, 150, 41, -]; - /// The seed of the metadata account PDA. pub const METADATA: &[u8] = b"metadata"; - -/// The bump of the mint authority account, for cpis. -pub const MINT_AUTHORITY_BUMP: u8 = - ed25519::derive_program_address(&[MINT_AUTHORITY], &PROGRAM_ID).1; diff --git a/tokens/pda-mint-authority/steel/api/src/error.rs b/tokens/pda-mint-authority/steel/api/src/error.rs deleted file mode 100644 index 96e84da4d..000000000 --- a/tokens/pda-mint-authority/steel/api/src/error.rs +++ /dev/null @@ -1,10 +0,0 @@ -use steel::*; - -#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] -#[repr(u32)] -pub enum SteelError { - #[error("This is a dummy error")] - Dummy = 0, -} - -error!(SteelError); diff --git a/tokens/pda-mint-authority/steel/api/src/instruction.rs b/tokens/pda-mint-authority/steel/api/src/instruction.rs index 9f09492d7..0c70cea5d 100644 --- a/tokens/pda-mint-authority/steel/api/src/instruction.rs +++ b/tokens/pda-mint-authority/steel/api/src/instruction.rs @@ -3,18 +3,21 @@ use steel::*; #[repr(u8)] #[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] pub enum SteelInstruction { - Create = 0, - Mint = 1, + Init = 0, + Create = 1, + Mint = 2, } +#[repr(C)] +#[derive(Clone, Copy, Debug, Pod, Zeroable)] +pub struct Init {} + #[repr(C)] #[derive(Clone, Copy, Debug, Pod, Zeroable)] pub struct Create { pub token_name: [u8; 32], pub token_symbol: [u8; 8], pub token_uri: [u8; 64], - pub mint_authority_bump: u8, - pub mint_bump: u8, } #[repr(C)] @@ -23,5 +26,6 @@ pub struct Mint { pub amount: [u8; 8], } +instruction!(SteelInstruction, Init); instruction!(SteelInstruction, Create); instruction!(SteelInstruction, Mint); diff --git a/tokens/pda-mint-authority/steel/api/src/lib.rs b/tokens/pda-mint-authority/steel/api/src/lib.rs index aed2ed84f..6db8ac73d 100644 --- a/tokens/pda-mint-authority/steel/api/src/lib.rs +++ b/tokens/pda-mint-authority/steel/api/src/lib.rs @@ -1,18 +1,16 @@ pub mod consts; -pub mod error; pub mod instruction; pub mod sdk; pub mod state; pub mod prelude { pub use crate::consts::*; - pub use crate::error::*; pub use crate::instruction::*; pub use crate::sdk::*; - pub use crate::state::*; + pub use crate::state::*; } use steel::*; // TODO Set program id -declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35"); +declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35"); diff --git a/tokens/pda-mint-authority/steel/api/src/sdk.rs b/tokens/pda-mint-authority/steel/api/src/sdk.rs index aec6fadca..7099778f5 100644 --- a/tokens/pda-mint-authority/steel/api/src/sdk.rs +++ b/tokens/pda-mint-authority/steel/api/src/sdk.rs @@ -2,32 +2,29 @@ use steel::*; use crate::prelude::*; +pub fn init(payer: Pubkey) -> Instruction { + let mint_authority_pda = mint_authority_pda(); + + Instruction { + program_id: crate::ID, + accounts: vec![ + AccountMeta::new(mint_authority_pda.0, false), + AccountMeta::new(payer, false), + AccountMeta::new_readonly(system_program::ID, false), + ], + data: Init {}.to_bytes(), + } +} + pub fn create( payer: Pubkey, - token_name: String, - token_symbol: String, - token_uri: String, + mint: Pubkey, + token_name: [u8; 32], + token_symbol: [u8; 8], + token_uri: [u8; 64], ) -> Instruction { - let token_name_bytes: [u8; 32] = token_name - .as_bytes() - .try_into() - .expect("String wrong length, expected 32 bytes"); - let token_symbol_bytes: [u8; 8] = token_symbol - .as_bytes() - .try_into() - .expect("String wrong length, expected 32 bytes"); - let token_uri_bytes: [u8; 64] = token_uri - .as_bytes() - .try_into() - .expect("String wrong length, expected 32 bytes"); - - let mint_pda = Pubkey::find_program_address(&[MINT, MINT_NOISE.as_slice()], &crate::ID); let metadata_pda = Pubkey::find_program_address( - &[ - METADATA, - mpl_token_metadata::ID.as_ref(), - mint_pda.0.as_ref(), - ], + &[METADATA, mpl_token_metadata::ID.as_ref(), mint.as_ref()], &mpl_token_metadata::ID, ); let mint_authority_pda = mint_authority_pda(); @@ -35,40 +32,41 @@ pub fn create( Instruction { program_id: crate::ID, accounts: vec![ - AccountMeta::new(payer, true), - AccountMeta::new(mint_pda.0, false), + AccountMeta::new(mint, true), AccountMeta::new(mint_authority_pda.0, false), AccountMeta::new(metadata_pda.0, false), + AccountMeta::new(payer, true), AccountMeta::new_readonly(system_program::ID, false), AccountMeta::new_readonly(spl_token::ID, false), AccountMeta::new_readonly(mpl_token_metadata::ID, false), AccountMeta::new_readonly(sysvar::rent::ID, false), ], data: Create { - token_name: token_name_bytes, - token_symbol: token_symbol_bytes, - token_uri: token_uri_bytes, - mint_authority_bump: mint_authority_pda.1, - mint_bump: mint_pda.1, + token_name, + token_symbol, + token_uri, } .to_bytes(), } } pub fn mint( - signer: Pubkey, + payer: Pubkey, mint: Pubkey, - to: Pubkey, - authority: Pubkey, + associated_token_account: Pubkey, amount: u64, ) -> Instruction { + let mint_authority_pda = mint_authority_pda(); + Instruction { program_id: crate::ID, accounts: vec![ - AccountMeta::new(signer, true), + AccountMeta::new(payer, true), AccountMeta::new(mint, false), - AccountMeta::new(to, false), - AccountMeta::new(authority, false), + AccountMeta::new(associated_token_account, false), + AccountMeta::new(mint_authority_pda.0, false), AccountMeta::new_readonly(spl_token::ID, false), + AccountMeta::new_readonly(spl_associated_token_account::ID, false), + AccountMeta::new_readonly(system_program::ID, false), ], data: Mint { amount: amount.to_le_bytes(), diff --git a/tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs b/tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs index 8d8bbf9f0..bd0a7704c 100644 --- a/tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs +++ b/tokens/pda-mint-authority/steel/api/src/state/mint_authority.rs @@ -5,7 +5,7 @@ use super::SteelAccount; #[repr(C)] #[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] pub struct MintAuthorityPda { - bump: u8, + pub bump: u8, } account!(SteelAccount, MintAuthorityPda); diff --git a/tokens/pda-mint-authority/steel/api/src/state/mod.rs b/tokens/pda-mint-authority/steel/api/src/state/mod.rs index e3c9bdca3..c29fb1862 100644 --- a/tokens/pda-mint-authority/steel/api/src/state/mod.rs +++ b/tokens/pda-mint-authority/steel/api/src/state/mod.rs @@ -12,7 +12,7 @@ pub enum SteelAccount { MintAuthorityPda = 0, } -/// Fetch PDA of the counter account. +/// Fetch PDA of the mint authority account. pub fn mint_authority_pda() -> (Pubkey, u8) { Pubkey::find_program_address(&[MINT_AUTHORITY], &crate::id()) } diff --git a/tokens/pda-mint-authority/steel/program/Cargo.toml b/tokens/pda-mint-authority/steel/program/Cargo.toml index 0c8c7bd98..117641116 100644 --- a/tokens/pda-mint-authority/steel/program/Cargo.toml +++ b/tokens/pda-mint-authority/steel/program/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "steel-program" +name = "pda-mint-authority-program" version = "0.1.0" edition = "2021" @@ -7,14 +7,15 @@ edition = "2021" crate-type = ["cdylib", "lib"] [dependencies] -steel-api.workspace = true +pda-mint-authority-api.workspace = true solana-program.workspace = true steel.workspace = true spl-token.workspace = true mpl-token-metadata.workspace = true +spl-associated-token-account.workspace = true [dev-dependencies] -bs64 = "0.1.2" +base64 = "0.21" rand = "0.8.5" solana-program-test = "1.18" solana-sdk = "1.18" diff --git a/tokens/pda-mint-authority/steel/program/build.rs b/tokens/pda-mint-authority/steel/program/build.rs new file mode 100644 index 000000000..e4ff00ff7 --- /dev/null +++ b/tokens/pda-mint-authority/steel/program/build.rs @@ -0,0 +1,24 @@ +// build.rs +use std::fs; +use std::process::Command; + +fn main() { + println!("cargo:rerun-if-changed=build.rs"); + + // Create the fixtures directory path + fs::create_dir_all("tests/fixtures").expect("Failed to create fixtures directory"); + + let status = Command::new("solana") + .args([ + "program", + "dump", + "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", + "tests/fixtures/token_metadata.so", + ]) + .status() + .expect("Failed to run solana program dump command"); + + if !status.success() { + panic!("Failed to dump Solana program"); + } +} diff --git a/tokens/pda-mint-authority/steel/program/src/create.rs b/tokens/pda-mint-authority/steel/program/src/create.rs index 136c6cd3b..01cb9b585 100644 --- a/tokens/pda-mint-authority/steel/program/src/create.rs +++ b/tokens/pda-mint-authority/steel/program/src/create.rs @@ -1,8 +1,8 @@ +use pda_mint_authority_api::prelude::*; use solana_program::msg; use solana_program::program_pack::Pack; use spl_token::state::Mint; use steel::*; -use steel_api::prelude::*; pub fn process_create(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { // parse args. @@ -12,48 +12,44 @@ pub fn process_create(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResul let token_uri = String::from_utf8(args.token_uri.to_vec()).expect("Invalid UTF-8"); // Load accounts. - let [payer_info, mint_info, mint_authority_info, metadata_info, token_program, system_program, rent_sysvar, token_metadata_program] = + let [mint_info, mint_authority_info, metadata_info, payer_info, system_program, token_program, token_metadata_program, rent_sysvar] = accounts else { return Err(ProgramError::NotEnoughAccountKeys); }; - // validation payer_info.is_signer()?; - mint_info.to_mint()?; - token_program.is_program(&spl_token::ID)?; + mint_info.is_empty()?.is_writable()?; rent_sysvar.is_sysvar(&sysvar::rent::ID)?; system_program.is_program(&system_program::ID)?; token_program.is_program(&spl_token::ID)?; - token_metadata_program.is_program(&mpl_token_metadata::ID)?; - rent_sysvar.is_sysvar(&sysvar::rent::ID)?; + msg!("{:?}", token_metadata_program.is_executable()); - mint_authority_info.is_empty()?.is_writable()?.has_seeds( - &[MINT_AUTHORITY], - args.mint_authority_bump, - &steel_api::ID, - )?; + let (mint_authority_pda, bump) = mint_authority_pda(); + assert!(&mint_authority_pda.eq(mint_authority_info.key)); - // Initialize mint authority. - create_account::( - mint_authority_info, - &steel_api::ID, - &[MINT_AUTHORITY, &[args.mint_authority_bump]], - system_program, - payer_info, - )?; + mint_authority_info + .is_writable()? + .has_seeds(&[MINT_AUTHORITY], &pda_mint_authority_api::ID)?; // First create the account for the Mint // msg!("Creating mint account..."); msg!("Mint: {}", mint_info.key); - allocate_account( - mint_info, - &spl_token::ID, - Mint::LEN, - &[MINT, MINT_NOISE.as_slice(), &[args.mint_bump]], - system_program, - payer_info, + solana_program::program::invoke( + &solana_program::system_instruction::create_account( + payer_info.key, + mint_info.key, + (solana_program::rent::Rent::get()?).minimum_balance(Mint::LEN), + Mint::LEN as u64, + token_program.key, + ), + &[ + mint_info.clone(), + payer_info.clone(), + system_program.clone(), + token_program.clone(), + ], )?; // Now initialize that account as a Mint (standard Mint) @@ -62,7 +58,7 @@ pub fn process_create(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResul msg!("Mint: {}", mint_info.key); solana_program::program::invoke( &spl_token::instruction::initialize_mint( - &spl_token::ID, + token_program.key, mint_info.key, mint_authority_info.key, Some(mint_authority_info.key), @@ -103,7 +99,7 @@ pub fn process_create(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResul collection_details: None, }, } - .invoke_signed(&[&[MINT_AUTHORITY, &[args.mint_authority_bump]]])?; + .invoke_signed(&[&[MINT_AUTHORITY, &[bump]]])?; msg!("Token mint created successfully."); diff --git a/tokens/pda-mint-authority/steel/program/src/init.rs b/tokens/pda-mint-authority/steel/program/src/init.rs new file mode 100644 index 000000000..4d2bc4da9 --- /dev/null +++ b/tokens/pda-mint-authority/steel/program/src/init.rs @@ -0,0 +1,35 @@ +use pda_mint_authority_api::prelude::*; +use solana_program::msg; +use steel::*; + +pub fn process_init(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult { + // Load accounts. + let [mint_authority_info, payer_info, system_program] = accounts else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + // validation + payer_info.is_signer()?; + mint_authority_info + .is_empty()? + .is_writable()? + .has_seeds(&[MINT_AUTHORITY], &pda_mint_authority_api::ID)?; + system_program.is_program(&system_program::ID)?; + + msg!("Creating mint authority PDA..."); + msg!("Mint Authority: {}", &mint_authority_info.key); + create_account::( + mint_authority_info, + system_program, + payer_info, + &pda_mint_authority_api::ID, + &[MINT_AUTHORITY], + )?; + + let mint_authority = + mint_authority_info.as_account_mut::(&pda_mint_authority_api::ID)?; + let mint_authority_bump = mint_authority_pda().1; + mint_authority.bump = mint_authority_bump; + + Ok(()) +} diff --git a/tokens/pda-mint-authority/steel/program/src/lib.rs b/tokens/pda-mint-authority/steel/program/src/lib.rs index 85b853681..59a3bfac1 100644 --- a/tokens/pda-mint-authority/steel/program/src/lib.rs +++ b/tokens/pda-mint-authority/steel/program/src/lib.rs @@ -1,22 +1,25 @@ mod create; +mod init; mod mint; pub use create::*; +pub use init::*; pub use mint::*; +use pda_mint_authority_api::prelude::*; use steel::*; -use steel_api::prelude::*; pub fn process_instruction( program_id: &Pubkey, accounts: &[AccountInfo], data: &[u8], ) -> ProgramResult { - let (ix, data) = parse_instruction(&steel_api::ID, program_id, data)?; + let (ix, data) = parse_instruction(&pda_mint_authority_api::ID, program_id, data)?; match ix { SteelInstruction::Create => process_create(accounts, data)?, SteelInstruction::Mint => process_mint(accounts, data)?, + SteelInstruction::Init => process_init(accounts, data)?, } Ok(()) diff --git a/tokens/pda-mint-authority/steel/program/src/mint.rs b/tokens/pda-mint-authority/steel/program/src/mint.rs index 8e37844ae..e26ff544f 100644 --- a/tokens/pda-mint-authority/steel/program/src/mint.rs +++ b/tokens/pda-mint-authority/steel/program/src/mint.rs @@ -1,6 +1,6 @@ +use pda_mint_authority_api::prelude::*; use solana_program::msg; use steel::*; -use steel_api::prelude::*; pub fn process_mint(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { // parse args. @@ -8,43 +8,64 @@ pub fn process_mint(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult let amount = u64::from_le_bytes(args.amount); // Load accounts. - let [signer_info, mint_info, to_info, authority_info, token_program] = accounts else { + let [payer_info, mint_info, ata_info, mint_authority_info, token_program, associated_token_program, system_program] = + accounts + else { return Err(ProgramError::NotEnoughAccountKeys); }; msg!("Minting tokens to associated token account..."); msg!("Mint: {:?}", mint_info); - msg!("Token Address: {:?}", &to_info); + msg!("Token Address: {:?}", &ata_info); // validation - signer_info.is_signer()?; - mint_info.to_mint()?; + payer_info.is_signer()?; + mint_info.as_mint()?; token_program.is_program(&spl_token::ID)?; - to_info + if ata_info.lamports() == 0 { + msg!("Creating associated token account..."); + create_associated_token_account( + payer_info, + payer_info, + ata_info, + mint_info, + system_program, + token_program, + associated_token_program, + )?; + msg!("Associated Token Address: {}", ata_info.key); + } else { + msg!("Associated token account exists."); + } + + mint_authority_info + .is_writable()? + .has_seeds(&[MINT_AUTHORITY], &pda_mint_authority_api::ID)?; + ata_info .is_writable()? - .to_associated_token_account(signer_info.key, mint_info.key)? - .check(|t| t.owner == *signer_info.key)? - .check(|t| t.mint == *mint_info.key)?; + .as_associated_token_account(payer_info.key, mint_info.key)?; - token_program.is_program(&spl_token::ID)?; + msg!("Minting token to associated token account..."); + msg!("Mint: {}", mint_info.key); + msg!("Token Address: {}", ata_info.key); solana_program::program::invoke_signed( &spl_token::instruction::mint_to( &spl_token::id(), mint_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], + ata_info.key, + mint_authority_info.key, + &[mint_authority_info.key], amount, )?, &[ token_program.clone(), mint_info.clone(), - to_info.clone(), - authority_info.clone(), + ata_info.clone(), + mint_authority_info.clone(), ], - &[&[MINT_AUTHORITY, &[MINT_AUTHORITY_BUMP]]], + &[&[MINT_AUTHORITY, &[mint_authority_pda().1]]], )?; msg!("Token minted successfully."); diff --git a/tokens/pda-mint-authority/steel/program/tests/test.rs b/tokens/pda-mint-authority/steel/program/tests/test.rs index c5bb50e1b..c80dd2751 100644 --- a/tokens/pda-mint-authority/steel/program/tests/test.rs +++ b/tokens/pda-mint-authority/steel/program/tests/test.rs @@ -1,15 +1,17 @@ -use steel_api::prelude::*; +use pda_mint_authority_api::prelude::*; use solana_program::hash::Hash; use solana_program_test::{processor, BanksClient, ProgramTest}; use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction}; -use steel::*; async fn setup() -> (BanksClient, Keypair, Hash) { let mut program_test = ProgramTest::new( - "steel", - steel_api::ID, - processor!(steel_program::process_instruction), + "pda_mint_authority_program", + pda_mint_authority_api::ID, + processor!(pda_mint_authority_program::process_instruction), ); + + program_test.add_program("token_metadata", mpl_token_metadata::ID, None); + program_test.prefer_bpf(true); program_test.start().await } @@ -18,29 +20,50 @@ async fn setup() -> (BanksClient, Keypair, Hash) { async fn run_test() { // Setup test let (mut banks, payer, blockhash) = setup().await; + let token_mint_keypair = Keypair::new(); + + let name = str_to_bytes::<32>("Solana Gold"); + let symbol = str_to_bytes::<8>("GOLDSOL"); + let uri = str_to_bytes::<64>("https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json"); - // Submit initialize transaction. - let ix = initialize(payer.pubkey()); + // Submit init transaction. + let ix = init(payer.pubkey()); let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash); let res = banks.process_transaction(tx).await; assert!(res.is_ok()); - // Verify counter was initialized. - let counter_address = counter_pda().0; - let counter_account = banks.get_account(counter_address).await.unwrap().unwrap(); - let counter = Counter::try_from_bytes(&counter_account.data).unwrap(); - assert_eq!(counter_account.owner, steel_api::ID); - assert_eq!(counter.value, 0); + // Submit create transaction for spl token. + let ix = create( + payer.pubkey(), + token_mint_keypair.pubkey(), + name, + symbol, + uri, + ); + let tx = Transaction::new_signed_with_payer( + &[ix], + Some(&payer.pubkey()), + &[&payer, &token_mint_keypair], + blockhash, + ); + let res = banks.process_transaction(tx).await; + assert!(res.is_ok()); + + let to_ata = spl_associated_token_account::get_associated_token_address( + &payer.pubkey(), + &token_mint_keypair.pubkey(), + ); - // Submit add transaction. - let ix = add(payer.pubkey(), 42); + // Submit mint transaction. + let ix = mint(payer.pubkey(), token_mint_keypair.pubkey(), to_ata, 100); let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash); let res = banks.process_transaction(tx).await; assert!(res.is_ok()); - - // Verify counter was incremented. - let counter_account = banks.get_account(counter_address).await.unwrap().unwrap(); - let counter = Counter::try_from_bytes(&counter_account.data).unwrap(); - assert_eq!(counter.value, 42); } +pub fn str_to_bytes(str: &str) -> [u8; N] { + let mut str_bytes = [0u8; N]; + let copy_len = str.len().min(N); + str_bytes[..copy_len].copy_from_slice(&str.as_bytes()[..copy_len]); + str_bytes +} From 442f1115840ca6876af41d1c490224e8d408b856 Mon Sep 17 00:00:00 2001 From: Perelyn <64838956+Perelyn-sama@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:43:11 +0100 Subject: [PATCH 3/5] add bankrun tests --- tokens/pda-mint-authority/steel/cicd.sh | 8 + tokens/pda-mint-authority/steel/package.json | 28 + .../pda-mint-authority/steel/pnpm-lock.yaml | 1860 +++++++++++++++++ tokens/pda-mint-authority/steel/prepare.mjs | 34 + .../steel/tests/instructions.ts | 91 + .../pda-mint-authority/steel/tests/tests.ts | 169 ++ tokens/pda-mint-authority/steel/tsconfig.json | 10 + 7 files changed, 2200 insertions(+) create mode 100644 tokens/pda-mint-authority/steel/cicd.sh create mode 100644 tokens/pda-mint-authority/steel/package.json create mode 100644 tokens/pda-mint-authority/steel/pnpm-lock.yaml create mode 100644 tokens/pda-mint-authority/steel/prepare.mjs create mode 100644 tokens/pda-mint-authority/steel/tests/instructions.ts create mode 100644 tokens/pda-mint-authority/steel/tests/tests.ts create mode 100644 tokens/pda-mint-authority/steel/tsconfig.json diff --git a/tokens/pda-mint-authority/steel/cicd.sh b/tokens/pda-mint-authority/steel/cicd.sh new file mode 100644 index 000000000..8a16e0387 --- /dev/null +++ b/tokens/pda-mint-authority/steel/cicd.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# This script is for quick building & deploying of the program. +# It also serves as a reference for the commands used for building & deploying Solana programs. +# Run this bad boy with "bash cicd.sh" or "./cicd.sh" + +cargo build-sbf --manifest-path=./program/Cargo.toml +solana program deploy ./program/target/deploy/program.so diff --git a/tokens/pda-mint-authority/steel/package.json b/tokens/pda-mint-authority/steel/package.json new file mode 100644 index 000000000..b1e1d3fa4 --- /dev/null +++ b/tokens/pda-mint-authority/steel/package.json @@ -0,0 +1,28 @@ +{ + "scripts": { + "test": "pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/tests.ts", + "build-and-test": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures && pnpm test", + "build": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so", + "deploy": "solana program deploy ./program/target/so/pda_mint_authority_program.so", + "postinstall": "zx prepare.mjs" + }, + "dependencies": { + "@metaplex-foundation/mpl-token-metadata": "^2.5.2", + "@solana/spl-token": "^0.3.7", + "@solana/web3.js": "^1.73.0", + "borsh": "^0.7.0", + "buffer": "^6.0.3", + "fs": "^0.0.1-security" + }, + "devDependencies": { + "@types/bn.js": "^5.1.0", + "@types/chai": "^4.3.1", + "@types/mocha": "^9.1.1", + "chai": "^4.3.4", + "mocha": "^9.0.3", + "ts-mocha": "^10.0.0", + "typescript": "^4.3.5", + "solana-bankrun": "^0.4.0", + "zx": "^8.1.4" + } +} diff --git a/tokens/pda-mint-authority/steel/pnpm-lock.yaml b/tokens/pda-mint-authority/steel/pnpm-lock.yaml new file mode 100644 index 000000000..787a11db3 --- /dev/null +++ b/tokens/pda-mint-authority/steel/pnpm-lock.yaml @@ -0,0 +1,1860 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@metaplex-foundation/mpl-token-metadata': + specifier: ^2.5.2 + version: 2.13.0(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/spl-token': + specifier: ^0.3.7 + version: 0.3.11(@solana/web3.js@1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': + specifier: ^1.73.0 + version: 1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + borsh: + specifier: ^0.7.0 + version: 0.7.0 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + fs: + specifier: ^0.0.1-security + version: 0.0.1-security + devDependencies: + '@types/bn.js': + specifier: ^5.1.0 + version: 5.1.6 + '@types/chai': + specifier: ^4.3.1 + version: 4.3.20 + '@types/mocha': + specifier: ^9.1.1 + version: 9.1.1 + chai: + specifier: ^4.3.4 + version: 4.5.0 + mocha: + specifier: ^9.0.3 + version: 9.2.2 + solana-bankrun: + specifier: ^0.4.0 + version: 0.4.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ts-mocha: + specifier: ^10.0.0 + version: 10.0.0(mocha@9.2.2) + typescript: + specifier: ^4.3.5 + version: 4.9.5 + zx: + specifier: ^8.1.4 + version: 8.1.9 + +packages: + + '@babel/runtime@7.26.0': + resolution: {integrity: sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==} + engines: {node: '>=6.9.0'} + + '@metaplex-foundation/beet-solana@0.4.1': + resolution: {integrity: sha512-/6o32FNUtwK8tjhotrvU/vorP7umBuRFvBZrC6XCk51aKidBHe5LPVPA5AjGPbV3oftMfRuXPNd9yAGeEqeCDQ==} + + '@metaplex-foundation/beet@0.7.2': + resolution: {integrity: sha512-K+g3WhyFxKPc0xIvcIjNyV1eaTVJTiuaHZpig7Xx0MuYRMoJLLvhLTnUXhFdR5Tu2l2QSyKwfyXDgZlzhULqFg==} + + '@metaplex-foundation/cusper@0.0.2': + resolution: {integrity: sha512-S9RulC2fFCFOQraz61bij+5YCHhSO9llJegK8c8Y6731fSi6snUSQJdCUqYS8AIgR0TKbQvdvgSyIIdbDFZbBA==} + + '@metaplex-foundation/mpl-token-metadata@2.13.0': + resolution: {integrity: sha512-Fl/8I0L9rv4bKTV/RAl5YIbJe9SnQPInKvLz+xR1fEc4/VQkuCn3RPgypfUMEKWmCznzaw4sApDxy6CFS4qmJw==} + + '@noble/curves@1.6.0': + resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.5.0': + resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} + engines: {node: ^14.21.3 || >=16} + + '@solana/buffer-layout-utils@0.2.0': + resolution: {integrity: sha512-szG4sxgJGktbuZYDg2FfNmkMi0DYQoVjN2h7ta1W1hPrwzarcFLBq9UpX1UjNXsNpT9dn+chgprtWGioUAr4/g==} + engines: {node: '>= 10'} + + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/codecs-core@2.0.0-rc.1': + resolution: {integrity: sha512-bauxqMfSs8EHD0JKESaNmNuNvkvHSuN3bbWAF5RjOfDu2PugxHrvRebmYauvSumZ3cTfQ4HJJX6PG5rN852qyQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-data-structures@2.0.0-rc.1': + resolution: {integrity: sha512-rinCv0RrAVJ9rE/rmaibWJQxMwC5lSaORSZuwjopSUE6T0nb/MVg6Z1siNCXhh/HFTOg0l8bNvZHgBcN/yvXog==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-numbers@2.0.0-rc.1': + resolution: {integrity: sha512-J5i5mOkvukXn8E3Z7sGIPxsThRCgSdgTWJDQeZvucQ9PT6Y3HiVXJ0pcWiOWAoQ3RX8e/f4I3IC+wE6pZiJzDQ==} + peerDependencies: + typescript: '>=5' + + '@solana/codecs-strings@2.0.0-rc.1': + resolution: {integrity: sha512-9/wPhw8TbGRTt6mHC4Zz1RqOnuPTqq1Nb4EyuvpZ39GW6O2t2Q7Q0XxiB3+BdoEjwA2XgPw6e2iRfvYgqty44g==} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5' + + '@solana/codecs@2.0.0-rc.1': + resolution: {integrity: sha512-qxoR7VybNJixV51L0G1RD2boZTcxmwUWnKCaJJExQ5qNKwbpSyDdWfFJfM5JhGyKe9DnPVOZB+JHWXnpbZBqrQ==} + peerDependencies: + typescript: '>=5' + + '@solana/errors@2.0.0-rc.1': + resolution: {integrity: sha512-ejNvQ2oJ7+bcFAYWj225lyRkHnixuAeb7RQCixm+5mH4n1IA4Qya/9Bmfy5RAAHQzxK43clu3kZmL5eF9VGtYQ==} + hasBin: true + peerDependencies: + typescript: '>=5' + + '@solana/options@2.0.0-rc.1': + resolution: {integrity: sha512-mLUcR9mZ3qfHlmMnREdIFPf9dpMc/Bl66tLSOOWxw4ml5xMT2ohFn7WGqoKcu/UHkT9CrC6+amEdqCNvUqI7AA==} + peerDependencies: + typescript: '>=5' + + '@solana/spl-token-metadata@0.1.6': + resolution: {integrity: sha512-7sMt1rsm/zQOQcUWllQX9mD2O6KhSAtY1hFR2hfFwgqfFWzSY9E9GDvFVNYUI1F0iQKcm6HmePU9QbKRXTEBiA==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.95.3 + + '@solana/spl-token@0.3.11': + resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} + engines: {node: '>=16'} + peerDependencies: + '@solana/web3.js': ^1.88.0 + + '@solana/web3.js@1.95.4': + resolution: {integrity: sha512-sdewnNEA42ZSMxqkzdwEWi6fDgzwtJHaQa5ndUGEJYtoOnM6X5cvPmjoTUp7/k7bRrVAxfBgDnvQQHD6yhlLYw==} + + '@swc/helpers@0.5.13': + resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + + '@types/bn.js@5.1.6': + resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + + '@types/mocha@9.1.1': + resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@22.8.4': + resolution: {integrity: sha512-SpNNxkftTJOPk0oN+y2bIqurEXHTA2AOZ3EJDDKeJ5VzkvvORSvmQXGQarcOzWV1ac7DCaPBEdMDxBsM+d8jWw==} + + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@types/ws@8.5.12': + resolution: {integrity: sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==} + + '@ungap/promise-all-settled@1.1.2': + resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} + + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + + agentkeepalive@4.5.0: + resolution: {integrity: sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==} + engines: {node: '>= 8.0.0'} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansicolors@0.3.2: + resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + assert@2.1.0: + resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@3.0.10: + resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} + + base-x@4.0.0: + resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bigint-buffer@1.1.5: + resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} + engines: {node: '>= 10.0.0'} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@5.0.0: + resolution: {integrity: sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + debug@4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + + diff@3.5.0: + resolution: {integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==} + engines: {node: '>=0.3.1'} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fs@0.0.1-security: + resolution: {integrity: sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + jayson@4.1.2: + resolution: {integrity: sha512-5nzMWDHy6f+koZOuYsArh2AXs73NfWYVlFyJJuCedr93GpY+Ku8qq10ropSXVfHK+H0T6paA88ww+/dV+1fBNA==} + engines: {node: '>=8'} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@4.2.1: + resolution: {integrity: sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==} + engines: {node: '>=10'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mocha@9.2.2: + resolution: {integrity: sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==} + engines: {node: '>= 12.0.0'} + hasBin: true + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.1: + resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.2: + resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==} + hasBin: true + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + rpc-websockets@9.0.4: + resolution: {integrity: sha512-yWZWN0M+bivtoNLnaDbtny4XchdAIF5Q4g/ZsC5UC61Ckbp0QczwO8fg44rV3uYmY4WHd+EZQbn90W1d8ojzqQ==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + solana-bankrun-darwin-arm64@0.4.0: + resolution: {integrity: sha512-6dz78Teoz7ez/3lpRLDjktYLJb79FcmJk2me4/YaB8WiO6W43OdExU4h+d2FyuAryO2DgBPXaBoBNY/8J1HJmw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + solana-bankrun-darwin-universal@0.4.0: + resolution: {integrity: sha512-zSSw/Jx3KNU42pPMmrEWABd0nOwGJfsj7nm9chVZ3ae7WQg3Uty0hHAkn5NSDCj3OOiN0py9Dr1l9vmRJpOOxg==} + engines: {node: '>= 10'} + os: [darwin] + + solana-bankrun-darwin-x64@0.4.0: + resolution: {integrity: sha512-LWjs5fsgHFtyr7YdJR6r0Ho5zrtzI6CY4wvwPXr8H2m3b4pZe6RLIZjQtabCav4cguc14G0K8yQB2PTMuGub8w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + solana-bankrun-linux-x64-gnu@0.4.0: + resolution: {integrity: sha512-SrlVrb82UIxt21Zr/XZFHVV/h9zd2/nP25PMpLJVLD7Pgl2yhkhfi82xj3OjxoQqWe+zkBJ+uszA0EEKr67yNw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + solana-bankrun-linux-x64-musl@0.4.0: + resolution: {integrity: sha512-Nv328ZanmURdYfcLL+jwB1oMzX4ZzK57NwIcuJjGlf0XSNLq96EoaO5buEiUTo4Ls7MqqMyLbClHcrPE7/aKyA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + solana-bankrun@0.4.0: + resolution: {integrity: sha512-NMmXUipPBkt8NgnyNO3SCnPERP6xT/AMNMBooljGA3+rG6NN8lmXJsKeLqQTiFsDeWD74U++QM/DgcueSWvrIg==} + engines: {node: '>= 10'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + superstruct@2.0.2: + resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} + engines: {node: '>=14.0.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-mocha@10.0.0: + resolution: {integrity: sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw==} + engines: {node: '>= 6.X.X'} + hasBin: true + peerDependencies: + mocha: ^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X + + ts-node@7.0.1: + resolution: {integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==} + engines: {node: '>=4.2.0'} + hasBin: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + workerpool@6.2.0: + resolution: {integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yn@2.0.0: + resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} + engines: {node: '>=4'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zx@8.1.9: + resolution: {integrity: sha512-UHuLHphHmsBYKkAchkSrEN4nzDyagafqC9HUxtc1J7eopaScW6H9dsLJ1lmkAntnLtDTGoM8fa+jrJrXiIfKFA==} + engines: {node: '>= 12.17.0'} + hasBin: true + +snapshots: + + '@babel/runtime@7.26.0': + dependencies: + regenerator-runtime: 0.14.1 + + '@metaplex-foundation/beet-solana@0.4.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@metaplex-foundation/beet': 0.7.2 + '@solana/web3.js': 1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bs58: 5.0.0 + debug: 4.3.7 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metaplex-foundation/beet@0.7.2': + dependencies: + ansicolors: 0.3.2 + assert: 2.1.0 + bn.js: 5.2.1 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + '@metaplex-foundation/cusper@0.0.2': {} + + '@metaplex-foundation/mpl-token-metadata@2.13.0(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': + dependencies: + '@metaplex-foundation/beet': 0.7.2 + '@metaplex-foundation/beet-solana': 0.4.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@metaplex-foundation/cusper': 0.0.2 + '@solana/spl-token': 0.3.11(@solana/web3.js@1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bn.js: 5.2.1 + debug: 4.3.7 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - supports-color + - typescript + - utf-8-validate + + '@noble/curves@1.6.0': + dependencies: + '@noble/hashes': 1.5.0 + + '@noble/hashes@1.5.0': {} + + '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/web3.js': 1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bigint-buffer: 1.1.5 + bignumber.js: 9.1.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@solana/buffer-layout@4.0.1': + dependencies: + buffer: 6.0.3 + + '@solana/codecs-core@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-data-structures@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-numbers@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-strings@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 4.9.5 + + '@solana/codecs@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/options': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@2.0.0-rc.1(typescript@4.9.5)': + dependencies: + chalk: 5.3.0 + commander: 12.1.0 + typescript: 4.9.5 + + '@solana/options@2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-data-structures': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-numbers': 2.0.0-rc.1(typescript@4.9.5) + '@solana/codecs-strings': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/errors': 2.0.0-rc.1(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/spl-token-metadata@0.1.6(@solana/web3.js@1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)': + dependencies: + '@solana/codecs': 2.0.0-rc.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - typescript + + '@solana/spl-token@0.3.11(@solana/web3.js@1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/spl-token-metadata': 0.1.6(@solana/web3.js@1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@4.9.5) + '@solana/web3.js': 1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + buffer: 6.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + '@solana/web3.js@1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.26.0 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@solana/buffer-layout': 4.0.1 + agentkeepalive: 4.5.0 + bigint-buffer: 1.1.5 + bn.js: 5.2.1 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.1.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + node-fetch: 2.7.0 + rpc-websockets: 9.0.4 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + '@swc/helpers@0.5.13': + dependencies: + tslib: 2.8.0 + + '@types/bn.js@5.1.6': + dependencies: + '@types/node': 22.8.4 + + '@types/chai@4.3.20': {} + + '@types/connect@3.4.38': + dependencies: + '@types/node': 12.20.55 + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 22.8.4 + optional: true + + '@types/json5@0.0.29': + optional: true + + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 22.8.4 + optional: true + + '@types/mocha@9.1.1': {} + + '@types/node@12.20.55': {} + + '@types/node@22.8.4': + dependencies: + undici-types: 6.19.8 + + '@types/uuid@8.3.4': {} + + '@types/ws@7.4.7': + dependencies: + '@types/node': 12.20.55 + + '@types/ws@8.5.12': + dependencies: + '@types/node': 22.8.4 + + '@ungap/promise-all-settled@1.1.2': {} + + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + agentkeepalive@4.5.0: + dependencies: + humanize-ms: 1.2.1 + + ansi-colors@4.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansicolors@0.3.2: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + argparse@2.0.1: {} + + arrify@1.0.1: {} + + assert@2.1.0: + dependencies: + call-bind: 1.0.7 + is-nan: 1.3.2 + object-is: 1.1.6 + object.assign: 4.1.5 + util: 0.12.5 + + assertion-error@1.1.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + balanced-match@1.0.2: {} + + base-x@3.0.10: + dependencies: + safe-buffer: 5.2.1 + + base-x@4.0.0: {} + + base64-js@1.5.1: {} + + bigint-buffer@1.1.5: + dependencies: + bindings: 1.5.0 + + bignumber.js@9.1.2: {} + + binary-extensions@2.3.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bn.js@5.2.1: {} + + borsh@0.7.0: + dependencies: + bn.js: 5.2.1 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browser-stdout@1.3.1: {} + + bs58@4.0.1: + dependencies: + base-x: 3.0.10 + + bs58@5.0.0: + dependencies: + base-x: 4.0.0 + + buffer-from@1.1.2: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.8.2 + optional: true + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + camelcase@6.3.0: {} + + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.3.0: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@12.1.0: {} + + commander@2.20.3: {} + + concat-map@0.0.1: {} + + debug@4.3.3(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + decamelize@4.0.0: {} + + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delay@5.0.0: {} + + diff@3.5.0: {} + + diff@5.0.0: {} + + emoji-regex@8.0.0: {} + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eventemitter3@5.0.1: {} + + eyes@0.1.8: {} + + fast-stable-stringify@1.0.0: {} + + fastestsmallesttextencoderdecoder@1.0.22: {} + + file-uri-to-path@1.0.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat@5.0.2: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + fs.realpath@1.0.0: {} + + fs@0.0.1-security: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + growl@1.10.5: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + ieee754@1.2.1: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-callable@1.2.7: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-nan@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + is-number@7.0.0: {} + + is-plain-obj@2.1.0: {} + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-unicode-supported@0.1.0: {} + + isexe@2.0.0: {} + + isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)): + dependencies: + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + + jayson@4.1.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + JSONStream: 1.3.5 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + json-stringify-safe: 5.0.1 + uuid: 8.3.2 + ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-stringify-safe@5.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + optional: true + + jsonparse@1.3.1: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + make-error@1.3.6: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@4.2.1: + dependencies: + brace-expansion: 1.1.11 + + minimist@1.2.8: {} + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mocha@9.2.2: + dependencies: + '@ungap/promise-all-settled': 1.1.2 + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.3(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 4.2.1 + ms: 2.1.3 + nanoid: 3.3.1 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + which: 2.0.2 + workerpool: 6.2.0 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + ms@2.1.2: {} + + ms@2.1.3: {} + + nanoid@3.3.1: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-gyp-build@4.8.2: + optional: true + + normalize-path@3.0.0: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + pathval@1.1.1: {} + + picomatch@2.3.1: {} + + possible-typed-array-names@1.0.0: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regenerator-runtime@0.14.1: {} + + require-directory@2.1.1: {} + + rpc-websockets@9.0.4: + dependencies: + '@swc/helpers': 0.5.13 + '@types/uuid': 8.3.4 + '@types/ws': 8.5.12 + buffer: 6.0.3 + eventemitter3: 5.0.1 + uuid: 8.3.2 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + safe-buffer@5.2.1: {} + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + solana-bankrun-darwin-arm64@0.4.0: + optional: true + + solana-bankrun-darwin-universal@0.4.0: + optional: true + + solana-bankrun-darwin-x64@0.4.0: + optional: true + + solana-bankrun-linux-x64-gnu@0.4.0: + optional: true + + solana-bankrun-linux-x64-musl@0.4.0: + optional: true + + solana-bankrun@0.4.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@solana/web3.js': 1.95.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bs58: 4.0.1 + optionalDependencies: + solana-bankrun-darwin-arm64: 0.4.0 + solana-bankrun-darwin-universal: 0.4.0 + solana-bankrun-darwin-x64: 0.4.0 + solana-bankrun-linux-x64-gnu: 0.4.0 + solana-bankrun-linux-x64-musl: 0.4.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@3.0.0: + optional: true + + strip-json-comments@3.1.1: {} + + superstruct@2.0.2: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + text-encoding-utf-8@1.0.2: {} + + through@2.3.8: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + ts-mocha@10.0.0(mocha@9.2.2): + dependencies: + mocha: 9.2.2 + ts-node: 7.0.1 + optionalDependencies: + tsconfig-paths: 3.15.0 + + ts-node@7.0.1: + dependencies: + arrify: 1.0.1 + buffer-from: 1.1.2 + diff: 3.5.0 + make-error: 1.3.6 + minimist: 1.2.8 + mkdirp: 0.5.6 + source-map-support: 0.5.21 + yn: 2.0.0 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + optional: true + + tslib@2.8.0: {} + + type-detect@4.1.0: {} + + typescript@4.9.5: {} + + undici-types@6.19.8: {} + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.2 + optional: true + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.15 + + uuid@8.3.2: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + workerpool@6.2.0: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + y18n@5.0.8: {} + + yargs-parser@20.2.4: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.4 + + yn@2.0.0: {} + + yocto-queue@0.1.0: {} + + zx@8.1.9: + optionalDependencies: + '@types/fs-extra': 11.0.4 + '@types/node': 22.8.4 diff --git a/tokens/pda-mint-authority/steel/prepare.mjs b/tokens/pda-mint-authority/steel/prepare.mjs new file mode 100644 index 000000000..fb6b26225 --- /dev/null +++ b/tokens/pda-mint-authority/steel/prepare.mjs @@ -0,0 +1,34 @@ +#!/usr/bin/env zx + +import { mkdir, rm } from "node:fs/promises"; +import { join } from "node:path"; +import { $ } from "zx"; + +const programs = [ + { + id: "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", + name: "token_metadata.so", + }, +]; + +const outputDir = "tests/fixtures"; +const overwrite = true; + +try { + for (const program of programs) { + const { id, name } = program; + const outputFile = join(outputDir, name); + await $`solana config set -um`; + + try { + await mkdir(outputDir, { recursive: true }); + if (overwrite) await rm(outputFile, { force: true }); + await $`solana program dump ${id} ${outputFile}`; + console.log(`Program ${id} dumped to ${outputFile}`); + } catch (error) { + console.error(`Error dumping ${id}: ${error.message}`); + } + } +} catch (error) { + console.error(`Error preparing programs: ${error.message}`); +} diff --git a/tokens/pda-mint-authority/steel/tests/instructions.ts b/tokens/pda-mint-authority/steel/tests/instructions.ts new file mode 100644 index 000000000..8097c1331 --- /dev/null +++ b/tokens/pda-mint-authority/steel/tests/instructions.ts @@ -0,0 +1,91 @@ +import { BN } from "bn.js"; + +class Assignable { + constructor(properties) { + for (const [key, value] of Object.entries(properties)) { + this[key] = value; + } + } +} + +// Helper function to pad strings to fixed length buffers +function strToBytes(str: string, length: number): Buffer { + const buffer = Buffer.alloc(length); + buffer.write(str); + return buffer; +} + +export enum PDAMintAuthorityInstruction { + Init = 0, + Create = 1, + Mint = 2, +} + +export class InitArgs { + instruction: number; + + constructor() { + this.instruction = PDAMintAuthorityInstruction.Init; + } + + toBuffer(): Buffer { + // Only need 1 byte for the instruction as there are no other fields + const buffer = Buffer.alloc(1); + buffer.writeUInt8(this.instruction, 0); + return buffer; + } +} + +export class CreateTokenArgs { + instruction: number; + name: Buffer; + symbol: Buffer; + uri: Buffer; + + constructor(name: string, symbol: string, uri: string) { + this.instruction = PDAMintAuthorityInstruction.Create; + this.name = strToBytes(name, 32); + this.symbol = strToBytes(symbol, 8); + this.uri = strToBytes(uri, 64); + } + + toBuffer(): Buffer { + const buffer = Buffer.alloc(1 + 32 + 8 + 64); + let offset = 0; + + buffer.writeUInt8(this.instruction, offset); + offset += 1; + + this.name.copy(buffer, offset); + offset += 32; + this.symbol.copy(buffer, offset); + offset += 8; + this.uri.copy(buffer, offset); + + return buffer; + } +} + +export class MintToArgs { + instruction: number; + quantity: BN; + + constructor(quantity: number) { + this.instruction = PDAMintAuthorityInstruction.Mint; + this.quantity = new BN(quantity); + } + + toBuffer(): Buffer { + const buffer = Buffer.alloc(9); // 1 byte for instruction + 8 bytes for u64 quantity + let offset = 0; + + // Write instruction + buffer.writeUInt8(this.instruction, offset); + offset += 1; + + // Write quantity as u64 LE (8 bytes) + this.quantity.toBuffer("le", 8).copy(buffer, offset); + + return buffer; + } +} diff --git a/tokens/pda-mint-authority/steel/tests/tests.ts b/tokens/pda-mint-authority/steel/tests/tests.ts new file mode 100644 index 000000000..d74844810 --- /dev/null +++ b/tokens/pda-mint-authority/steel/tests/tests.ts @@ -0,0 +1,169 @@ +import { Buffer } from "node:buffer"; +import { describe, test } from "node:test"; +import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from "@metaplex-foundation/mpl-token-metadata"; +import { + ASSOCIATED_TOKEN_PROGRAM_ID, + TOKEN_PROGRAM_ID, + getAssociatedTokenAddressSync, +} from "@solana/spl-token"; +import { + Keypair, + PublicKey, + SYSVAR_RENT_PUBKEY, + SystemProgram, + Transaction, + TransactionInstruction, +} from "@solana/web3.js"; +import { start } from "solana-bankrun"; +import { InitArgs, CreateTokenArgs, MintToArgs } from "./instructions"; + +describe("PDA MINT AUTHORITY", async () => { + const PROGRAM_ID = new PublicKey( + "z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35", + ); + const context = await start( + [ + { name: "pda_mint_authority_program", programId: PROGRAM_ID }, + { name: "token_metadata", programId: TOKEN_METADATA_PROGRAM_ID }, + ], + [], + ); + const client = context.banksClient; + const payer = context.payer; + + const mintKeypair: Keypair = Keypair.generate(); + const mintAuthorityPublicKey = PublicKey.findProgramAddressSync( + [Buffer.from("mint_authority")], + PROGRAM_ID, + )[0]; + + test("Init mind authority PDA!", async () => { + const metadataPDA = PublicKey.findProgramAddressSync( + [ + Buffer.from("metadata"), + TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mintKeypair.publicKey.toBuffer(), + ], + TOKEN_METADATA_PROGRAM_ID, + )[0]; + + const initArgs = new InitArgs(); + + const initIx = new TransactionInstruction({ + keys: [ + { pubkey: mintAuthorityPublicKey, isSigner: false, isWritable: true }, + { pubkey: payer.publicKey, isSigner: false, isWritable: true }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId: PROGRAM_ID, + data: initArgs.toBuffer(), + }); + + const tx = new Transaction(); + const [blockhash, _] = await client.getLatestBlockhash(); + tx.recentBlockhash = blockhash; + tx.add(initIx).sign(payer); + + await client.processTransaction(tx); + + console.log("Success!"); + console.log(` Mint Address: ${mintKeypair.publicKey}`); + }); + + test("Create a SPL Token with PDA!", async () => { + const metadataPDA = PublicKey.findProgramAddressSync( + [ + Buffer.from("metadata"), + TOKEN_METADATA_PROGRAM_ID.toBuffer(), + mintKeypair.publicKey.toBuffer(), + ], + TOKEN_METADATA_PROGRAM_ID, + )[0]; + + // SPL Token default = 9 decimals + // + const createArgs = new CreateTokenArgs( + "Solana Gold", + "GOLDSOL", + "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json", + ); + + const createTokenIx = new TransactionInstruction({ + keys: [ + { pubkey: mintKeypair.publicKey, isSigner: true, isWritable: true }, + { pubkey: mintAuthorityPublicKey, isSigner: false, isWritable: true }, + { pubkey: metadataPDA, isSigner: false, isWritable: true }, + { pubkey: payer.publicKey, isSigner: true, isWritable: true }, + { + pubkey: SystemProgram.programId, + isSigner: false, + isWritable: false, + }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, + { + pubkey: TOKEN_METADATA_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, + { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, + ], + programId: PROGRAM_ID, + data: createArgs.toBuffer(), + }); + + const tx = new Transaction(); + const [blockhash, _] = await client.getLatestBlockhash(); + tx.recentBlockhash = blockhash; + tx.add(createTokenIx).sign(payer, mintKeypair); + + await client.processTransaction(tx); + + console.log("Success!"); + console.log(` Mint Address: ${mintKeypair.publicKey}`); + }); + + test("Mint some tokens to your wallet with PDA!", async () => { + const associatedTokenAccountAddress = getAssociatedTokenAddressSync( + mintKeypair.publicKey, + payer.publicKey, + ); + + const mintArgs = new MintToArgs(100); + + const mintToIx = new TransactionInstruction({ + keys: [ + { pubkey: payer.publicKey, isSigner: true, isWritable: true }, // payer + { pubkey: mintKeypair.publicKey, isSigner: false, isWritable: true }, // mint_pda must be writable + { + pubkey: associatedTokenAccountAddress, + isSigner: false, + isWritable: true, + }, // ATA + { pubkey: mintAuthorityPublicKey, isSigner: false, isWritable: true }, + { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, // spl_token::ID + { + pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, + isSigner: false, + isWritable: false, + }, // spl_associated_token_account::ID + { + pubkey: SystemProgram.programId, + isSigner: false, + isWritable: false, + }, // system_program::ID + ], + programId: PROGRAM_ID, + data: mintArgs.toBuffer(), + }); + + const tx = new Transaction(); + const [blockhash, _] = await client.getLatestBlockhash(); + tx.recentBlockhash = blockhash; + tx.add(mintToIx).sign(payer); + + await client.processTransaction(tx); + + console.log("Success!"); + console.log(` ATA Address: ${associatedTokenAccountAddress}`); + }); +}); diff --git a/tokens/pda-mint-authority/steel/tsconfig.json b/tokens/pda-mint-authority/steel/tsconfig.json new file mode 100644 index 000000000..cd5d2e3d0 --- /dev/null +++ b/tokens/pda-mint-authority/steel/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "types": ["mocha", "chai"], + "typeRoots": ["./node_modules/@types"], + "lib": ["es2015"], + "module": "commonjs", + "target": "es6", + "esModuleInterop": true + } +} From 483c564a0d71a9ab5334f2520f5861430848a550 Mon Sep 17 00:00:00 2001 From: Perelyn <64838956+Perelyn-sama@users.noreply.github.com> Date: Wed, 20 Nov 2024 22:52:01 +0100 Subject: [PATCH 4/5] run pnpm fix --- tokens/pda-mint-authority/steel/prepare.mjs | 12 +-- .../steel/tests/instructions.ts | 4 +- .../pda-mint-authority/steel/tests/tests.ts | 77 ++++++------------- 3 files changed, 33 insertions(+), 60 deletions(-) diff --git a/tokens/pda-mint-authority/steel/prepare.mjs b/tokens/pda-mint-authority/steel/prepare.mjs index fb6b26225..7c5ec464b 100644 --- a/tokens/pda-mint-authority/steel/prepare.mjs +++ b/tokens/pda-mint-authority/steel/prepare.mjs @@ -1,17 +1,17 @@ #!/usr/bin/env zx -import { mkdir, rm } from "node:fs/promises"; -import { join } from "node:path"; -import { $ } from "zx"; +import { mkdir, rm } from 'node:fs/promises'; +import { join } from 'node:path'; +import { $ } from 'zx'; const programs = [ { - id: "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s", - name: "token_metadata.so", + id: 'metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s', + name: 'token_metadata.so', }, ]; -const outputDir = "tests/fixtures"; +const outputDir = 'tests/fixtures'; const overwrite = true; try { diff --git a/tokens/pda-mint-authority/steel/tests/instructions.ts b/tokens/pda-mint-authority/steel/tests/instructions.ts index 8097c1331..b96a79567 100644 --- a/tokens/pda-mint-authority/steel/tests/instructions.ts +++ b/tokens/pda-mint-authority/steel/tests/instructions.ts @@ -1,4 +1,4 @@ -import { BN } from "bn.js"; +import { BN } from 'bn.js'; class Assignable { constructor(properties) { @@ -84,7 +84,7 @@ export class MintToArgs { offset += 1; // Write quantity as u64 LE (8 bytes) - this.quantity.toBuffer("le", 8).copy(buffer, offset); + this.quantity.toBuffer('le', 8).copy(buffer, offset); return buffer; } diff --git a/tokens/pda-mint-authority/steel/tests/tests.ts b/tokens/pda-mint-authority/steel/tests/tests.ts index d74844810..eb821822f 100644 --- a/tokens/pda-mint-authority/steel/tests/tests.ts +++ b/tokens/pda-mint-authority/steel/tests/tests.ts @@ -1,30 +1,17 @@ -import { Buffer } from "node:buffer"; -import { describe, test } from "node:test"; -import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from "@metaplex-foundation/mpl-token-metadata"; -import { - ASSOCIATED_TOKEN_PROGRAM_ID, - TOKEN_PROGRAM_ID, - getAssociatedTokenAddressSync, -} from "@solana/spl-token"; -import { - Keypair, - PublicKey, - SYSVAR_RENT_PUBKEY, - SystemProgram, - Transaction, - TransactionInstruction, -} from "@solana/web3.js"; -import { start } from "solana-bankrun"; -import { InitArgs, CreateTokenArgs, MintToArgs } from "./instructions"; - -describe("PDA MINT AUTHORITY", async () => { - const PROGRAM_ID = new PublicKey( - "z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35", - ); +import { Buffer } from 'node:buffer'; +import { describe, test } from 'node:test'; +import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from '@metaplex-foundation/mpl-token-metadata'; +import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, getAssociatedTokenAddressSync } from '@solana/spl-token'; +import { Keypair, PublicKey, SYSVAR_RENT_PUBKEY, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js'; +import { start } from 'solana-bankrun'; +import { CreateTokenArgs, InitArgs, MintToArgs } from './instructions'; + +describe('PDA MINT AUTHORITY', async () => { + const PROGRAM_ID = new PublicKey('z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35'); const context = await start( [ - { name: "pda_mint_authority_program", programId: PROGRAM_ID }, - { name: "token_metadata", programId: TOKEN_METADATA_PROGRAM_ID }, + { name: 'pda_mint_authority_program', programId: PROGRAM_ID }, + { name: 'token_metadata', programId: TOKEN_METADATA_PROGRAM_ID }, ], [], ); @@ -32,18 +19,11 @@ describe("PDA MINT AUTHORITY", async () => { const payer = context.payer; const mintKeypair: Keypair = Keypair.generate(); - const mintAuthorityPublicKey = PublicKey.findProgramAddressSync( - [Buffer.from("mint_authority")], - PROGRAM_ID, - )[0]; + const mintAuthorityPublicKey = PublicKey.findProgramAddressSync([Buffer.from('mint_authority')], PROGRAM_ID)[0]; - test("Init mind authority PDA!", async () => { + test('Init mint authority PDA!', async () => { const metadataPDA = PublicKey.findProgramAddressSync( - [ - Buffer.from("metadata"), - TOKEN_METADATA_PROGRAM_ID.toBuffer(), - mintKeypair.publicKey.toBuffer(), - ], + [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), mintKeypair.publicKey.toBuffer()], TOKEN_METADATA_PROGRAM_ID, )[0]; @@ -66,26 +46,22 @@ describe("PDA MINT AUTHORITY", async () => { await client.processTransaction(tx); - console.log("Success!"); + console.log('Success!'); console.log(` Mint Address: ${mintKeypair.publicKey}`); }); - test("Create a SPL Token with PDA!", async () => { + test('Create a SPL Token with PDA!', async () => { const metadataPDA = PublicKey.findProgramAddressSync( - [ - Buffer.from("metadata"), - TOKEN_METADATA_PROGRAM_ID.toBuffer(), - mintKeypair.publicKey.toBuffer(), - ], + [Buffer.from('metadata'), TOKEN_METADATA_PROGRAM_ID.toBuffer(), mintKeypair.publicKey.toBuffer()], TOKEN_METADATA_PROGRAM_ID, )[0]; // SPL Token default = 9 decimals // const createArgs = new CreateTokenArgs( - "Solana Gold", - "GOLDSOL", - "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json", + 'Solana Gold', + 'GOLDSOL', + 'https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json', ); const createTokenIx = new TransactionInstruction({ @@ -118,15 +94,12 @@ describe("PDA MINT AUTHORITY", async () => { await client.processTransaction(tx); - console.log("Success!"); + console.log('Success!'); console.log(` Mint Address: ${mintKeypair.publicKey}`); }); - test("Mint some tokens to your wallet with PDA!", async () => { - const associatedTokenAccountAddress = getAssociatedTokenAddressSync( - mintKeypair.publicKey, - payer.publicKey, - ); + test('Mint some tokens to your wallet with PDA!', async () => { + const associatedTokenAccountAddress = getAssociatedTokenAddressSync(mintKeypair.publicKey, payer.publicKey); const mintArgs = new MintToArgs(100); @@ -163,7 +136,7 @@ describe("PDA MINT AUTHORITY", async () => { await client.processTransaction(tx); - console.log("Success!"); + console.log('Success!'); console.log(` ATA Address: ${associatedTokenAccountAddress}`); }); }); From 3c163525e5d26a9e4e78ceb496d3921ee49cd1be Mon Sep 17 00:00:00 2001 From: Perelyn <64838956+Perelyn-sama@users.noreply.github.com> Date: Sun, 24 Nov 2024 04:05:28 +0100 Subject: [PATCH 5/5] add solana check --- .../pda-mint-authority/steel/program/build.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/tokens/pda-mint-authority/steel/program/build.rs b/tokens/pda-mint-authority/steel/program/build.rs index e4ff00ff7..2c8fdeb01 100644 --- a/tokens/pda-mint-authority/steel/program/build.rs +++ b/tokens/pda-mint-authority/steel/program/build.rs @@ -2,9 +2,28 @@ use std::fs; use std::process::Command; +fn check_solana_installation() -> Result<(), String> { + match Command::new("solana").arg("--version").output() { + Ok(output) => { + if output.status.success() { + Ok(()) + } else { + Err("Solana CLI is available but returned an error".to_string()) + } + } + Err(e) => Err(format!("Solana CLI is not installed or not in PATH: {}", e)), + } +} + fn main() { println!("cargo:rerun-if-changed=build.rs"); + // Check if Solana is installed + if let Err(err) = check_solana_installation() { + println!("cargo:warning=Solana check failed: {}", err); + return; + } + // Create the fixtures directory path fs::create_dir_all("tests/fixtures").expect("Failed to create fixtures directory");