diff --git a/Cargo.lock b/Cargo.lock index 3cc0086..9c66b06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -982,11 +991,29 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "five8" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f76610e969fa1784327ded240f1e28a3fd9520c9cec93b636fcf62dd37f772" +dependencies = [ + "five8_core", +] + [[package]] name = "five8_const" -version = "0.1.3" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26dec3da8bc3ef08f2c04f61eab298c3ab334523e55f076354d6d6f613799a7b" +dependencies = [ + "five8_core", +] + +[[package]] +name = "five8_const" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b4f62f0f8ca357f93ae90c8c2dd1041a1f665fde2f889ea9b1787903829015" +checksum = "1a0f1728185f277989ca573a402716ae0beaaea3f76a8ff87ef9dd8fb19436c5" dependencies = [ "five8_core", ] @@ -1820,6 +1847,102 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +[[package]] +name = "pinocchio" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b971851087bc3699b001954ad02389d50c41405ece3548cbcafc88b3e20017a" + +[[package]] +name = "pinocchio" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfad955b2fe8f736e1ea276ebb31820d778ee69c1161146054e9b31be2e73326" +dependencies = [ + "solana-account-view", + "solana-address", + "solana-define-syscall 4.0.1", + "solana-instruction-view", + "solana-program-error 3.0.0", +] + +[[package]] +name = "pinocchio-associated-token-account" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd92823a97fb327d7509dfd7cbfa3ead56e9fc0e131972bc0e28ab7036be31a" +dependencies = [ + "solana-account-view", + "solana-address", + "solana-instruction-view", + "solana-program-error 3.0.0", +] + +[[package]] +name = "pinocchio-log" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd11022408f312e6179ece321c1f7dc0d1b2aa7765fddd39b2a7378d65a899e8" +dependencies = [ + "pinocchio-log-macro", +] + +[[package]] +name = "pinocchio-log-macro" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fb52edb3c5736b044cc462b0957b9767d0f574d138f4e2761438c498a4b467" +dependencies = [ + "quote", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "pinocchio-pubkey" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb0225638cadcbebae8932cb7f49cb5da7c15c21beb19f048f05a5ca7d93f065" +dependencies = [ + "five8_const 0.1.4", + "pinocchio 0.9.2", + "sha2-const-stable", +] + +[[package]] +name = "pinocchio-system" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24044a0815753862b558e179e78f03f7344cb755de48617a09d7d23b50883b6c" +dependencies = [ + "pinocchio 0.10.1", + "solana-address", +] + +[[package]] +name = "pinocchio-token" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "febf3bbe37f4e2723b9b41a1768c6542a1ae1b1d7bcac27f892f30cabcf70ec4" +dependencies = [ + "solana-account-view", + "solana-address", + "solana-instruction-view", + "solana-program-error 3.0.0", +] + +[[package]] +name = "pinocchio-token-2022" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbe4f1997ce2443f99333d8ae2ee1075f9c94ed13ff941178663ae3601ad99ad" +dependencies = [ + "solana-account-view", + "solana-address", + "solana-instruction-view", + "solana-program-error 3.0.0", +] + [[package]] name = "pkg-config" version = "0.3.31" @@ -1999,6 +2122,35 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + [[package]] name = "rpassword" version = "7.3.1" @@ -2188,6 +2340,12 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + [[package]] name = "sha3" version = "0.10.8" @@ -2250,11 +2408,35 @@ checksum = "fe9a5a802bc6ab2ba6a9d77580b038e7c2409932074f14fe35eaa64894a53c1e" dependencies = [ "bincode", "serde", - "solana-program-error", + "solana-program-error 2.1.9", "solana-program-memory", "solana-pubkey", ] +[[package]] +name = "solana-account-view" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f37ca34c37f92ee341b73d5ce7c8ef5bb38e9a87955b4bd343c63fa18b149215" +dependencies = [ + "solana-address", + "solana-program-error 3.0.0", +] + +[[package]] +name = "solana-address" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37320fd2945c5d654b2c6210624a52d66c3f1f73b653ed211ab91a703b35bdd" +dependencies = [ + "curve25519-dalek 4.1.3", + "five8", + "five8_const 1.0.0", + "solana-define-syscall 4.0.1", + "solana-program-error 3.0.0", + "solana-sha256-hasher 3.1.0", +] + [[package]] name = "solana-atomic-u64" version = "2.1.9" @@ -2372,9 +2554,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1b66925890e4108d10df357940da32ae01eea68d07b8da816eec4b93519db9d" dependencies = [ "solana-account-info", - "solana-define-syscall", + "solana-define-syscall 2.1.9", "solana-instruction", - "solana-program-error", + "solana-program-error 2.1.9", "solana-pubkey", "solana-stable-layout", ] @@ -2407,6 +2589,12 @@ version = "2.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d145184b5a9ada39c4cf1f5610cb33d342767c58f7fc87bd3b5ea51f183c2937" +[[package]] +name = "solana-define-syscall" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e5b1c0bc1d4a4d10c88a4100499d954c09d3fecfae4912c1a074dff68b1738" + [[package]] name = "solana-derivation-path" version = "2.1.9" @@ -2439,9 +2627,9 @@ dependencies = [ "lazy_static", "solana-clock", "solana-epoch-schedule", - "solana-hash", + "solana-hash 2.1.9", "solana-pubkey", - "solana-sha256-hasher", + "solana-sha256-hasher 2.1.9", ] [[package]] @@ -2473,6 +2661,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "solana-hash" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a5d48a6ee7b91fc7b998944ab026ed7b3e2fc8ee3bc58452644a86c2648152f" + [[package]] name = "solana-inflation" version = "2.1.9" @@ -2496,11 +2690,23 @@ dependencies = [ "num-traits", "serde", "serde_derive", - "solana-define-syscall", + "solana-define-syscall 2.1.9", "solana-pubkey", "wasm-bindgen", ] +[[package]] +name = "solana-instruction-view" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60147e4d0a4620013df40bf30a86dd299203ff12fcb8b593cd51014fce0875d8" +dependencies = [ + "solana-account-view", + "solana-address", + "solana-define-syscall 4.0.1", + "solana-program-error 3.0.0", +] + [[package]] name = "solana-last-restart-slot" version = "2.1.9" @@ -2519,7 +2725,7 @@ version = "2.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4818fcc8b1fa46f1d0c698a0645e0cf693baf4ab5654001fcaff4623187016cf" dependencies = [ - "solana-define-syscall", + "solana-define-syscall 2.1.9", ] [[package]] @@ -2571,7 +2777,7 @@ dependencies = [ "console_error_panic_hook", "console_log", "curve25519-dalek 4.1.3", - "five8_const", + "five8_const 0.1.4", "getrandom 0.2.15", "js-sys", "lazy_static", @@ -2594,16 +2800,16 @@ dependencies = [ "solana-clock", "solana-cpi", "solana-decode-error", - "solana-define-syscall", + "solana-define-syscall 2.1.9", "solana-epoch-schedule", "solana-fee-calculator", - "solana-hash", + "solana-hash 2.1.9", "solana-instruction", "solana-last-restart-slot", "solana-msg", "solana-native-token", "solana-program-entrypoint", - "solana-program-error", + "solana-program-error 2.1.9", "solana-program-memory", "solana-program-option", "solana-program-pack", @@ -2614,7 +2820,7 @@ dependencies = [ "solana-secp256k1-recover", "solana-serde-varint", "solana-serialize-utils", - "solana-sha256-hasher", + "solana-sha256-hasher 2.1.9", "solana-short-vec", "solana-slot-hashes", "solana-slot-history", @@ -2633,7 +2839,7 @@ checksum = "8f296f87584dbc684ed1fb00f849803358d97f663ec2829165052d50c2d30de3" dependencies = [ "solana-account-info", "solana-msg", - "solana-program-error", + "solana-program-error 2.1.9", "solana-pubkey", ] @@ -2653,6 +2859,12 @@ dependencies = [ "solana-pubkey", ] +[[package]] +name = "solana-program-error" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1af32c995a7b692a915bb7414d5f8e838450cf7c70414e763d8abcae7b51f28" + [[package]] name = "solana-program-memory" version = "2.1.9" @@ -2660,7 +2872,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "247aba89bb78002423229ac0c78d954f82ac02f493dbdecacaf94627fa18bdd1" dependencies = [ "num-traits", - "solana-define-syscall", + "solana-define-syscall 2.1.9", ] [[package]] @@ -2675,7 +2887,7 @@ version = "2.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23a1acbe8f1e2895659b06440f036cf3dd9949dbef0a123cefb3394a6d4192b2" dependencies = [ - "solana-program-error", + "solana-program-error 2.1.9", ] [[package]] @@ -2690,7 +2902,7 @@ dependencies = [ "bytemuck", "bytemuck_derive", "curve25519-dalek 4.1.3", - "five8_const", + "five8_const 0.1.4", "getrandom 0.2.15", "js-sys", "num-traits", @@ -2699,9 +2911,9 @@ dependencies = [ "serde_derive", "solana-atomic-u64", "solana-decode-error", - "solana-define-syscall", + "solana-define-syscall 2.1.9", "solana-sanitize", - "solana-sha256-hasher", + "solana-sha256-hasher 2.1.9", "wasm-bindgen", ] @@ -2827,7 +3039,7 @@ checksum = "e7a3642a378c45f5d6110048ef88848c1835ad079affc4804b833f9692906f24" dependencies = [ "borsh 1.5.4", "libsecp256k1", - "solana-define-syscall", + "solana-define-syscall 2.1.9", "thiserror 1.0.69", ] @@ -2878,8 +3090,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "700bb300ed088d6c216fa32a2f383d290a9981b52620f7a39b37963a78d0fedb" dependencies = [ "sha2 0.10.8", - "solana-define-syscall", - "solana-hash", + "solana-define-syscall 2.1.9", + "solana-hash 2.1.9", +] + +[[package]] +name = "solana-sha256-hasher" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db7dc3011ea4c0334aaaa7e7128cb390ecf546b28d412e9bf2064680f57f588f" +dependencies = [ + "sha2 0.10.8", + "solana-define-syscall 4.0.1", + "solana-hash 4.0.1", ] [[package]] @@ -2914,7 +3137,7 @@ checksum = "a25b7a24f410863eb9d2e69c19e412204c44cbaa338f45848a10111e0e100c94" dependencies = [ "serde", "serde_derive", - "solana-hash", + "solana-hash 2.1.9", "solana-sysvar-id", ] @@ -3058,8 +3281,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7398da23554a31660f17718164e31d31900956054f54f52d5ec1be51cb4f4b3" dependencies = [ "bytemuck", - "solana-program-error", - "solana-sha256-hasher", + "solana-program-error 2.1.9", + "solana-sha256-hasher 2.1.9", "spl-discriminator-derive", ] @@ -3110,7 +3333,7 @@ dependencies = [ "solana-instruction", "solana-msg", "solana-program-entrypoint", - "solana-program-error", + "solana-program-error 2.1.9", "solana-pubkey", ] @@ -3127,7 +3350,7 @@ dependencies = [ "num-traits", "solana-decode-error", "solana-msg", - "solana-program-error", + "solana-program-error 2.1.9", "solana-program-option", "solana-pubkey", "solana-zk-sdk", @@ -3172,7 +3395,7 @@ dependencies = [ "solana-decode-error", "solana-instruction", "solana-msg", - "solana-program-error", + "solana-program-error 2.1.9", "solana-pubkey", "spl-discriminator", "spl-pod", @@ -3327,7 +3550,7 @@ dependencies = [ "solana-decode-error", "solana-instruction", "solana-msg", - "solana-program-error", + "solana-program-error 2.1.9", "solana-pubkey", "spl-discriminator", "spl-pod", @@ -3347,7 +3570,7 @@ dependencies = [ "solana-decode-error", "solana-instruction", "solana-msg", - "solana-program-error", + "solana-program-error 2.1.9", "solana-pubkey", "spl-discriminator", "spl-pod", @@ -3370,7 +3593,7 @@ dependencies = [ "solana-decode-error", "solana-instruction", "solana-msg", - "solana-program-error", + "solana-program-error 2.1.9", "solana-pubkey", "spl-discriminator", "spl-pod", @@ -3392,7 +3615,7 @@ dependencies = [ "solana-account-info", "solana-decode-error", "solana-msg", - "solana-program-error", + "solana-program-error 2.1.9", "spl-discriminator", "spl-pod", "thiserror 1.0.69", @@ -3411,8 +3634,18 @@ dependencies = [ "bytemuck", "fixed", "num_enum", + "pinocchio 0.10.1", + "pinocchio-associated-token-account", + "pinocchio-log", + "pinocchio-pubkey", + "pinocchio-system", + "pinocchio-token", + "pinocchio-token-2022", "serde", - "solana-program", + "solana-account-view", + "solana-address", + "solana-instruction-view", + "solana-program-error 3.0.0", "spl-associated-token-account", "spl-token 4.0.2", "spl-token-2022 7.0.0", diff --git a/Cargo.toml b/Cargo.toml index a2ba99e..d3e776b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,18 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.137" solana-clap-v3-utils = "^2.1" solana-cli-config = "^2.1" -solana-program = "^2.1" +solana-address = { version = "2.0", features = ["decode", "curve25519"] } +solana-account-view = "1.0" +solana-program-error = "3.0" +solana-instruction-view = { version = "1.0.0", features = ["cpi"] } +pinocchio = { version = "0.10.1", features = ["cpi"] } +pinocchio-log = "0.5.1" +pinocchio-system = "0.5.0" +pinocchio-pubkey = "0.3.0" +pinocchio-associated-token-account = "0.3.0" +pinocchio-token-2022 = "0.2.0" +pinocchio-token = "0.5.0" +# solana-program = "^2.1" solana-sdk = "^2.1" spl-token = { features = ["no-entrypoint"], version = "^4" } spl-token-2022 = { features = ["no-entrypoint"], version = "^7" } @@ -38,4 +49,3 @@ thiserror = "1.0.57" tokio = "1.35" toml = "0.8.19" quote = "1.0" - diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 68c1fdc..8f18662 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -19,9 +19,20 @@ bytemuck.workspace = true fixed.workspace = true num_enum.workspace = true serde.workspace = true -solana-program.workspace = true +# solana-program.workspace = true +solana-address.workspace = true +solana-account-view.workspace = true +solana-program-error.workspace = true +solana-instruction-view.workspace = true spl-token = { workspace = true, optional = true } spl-token-2022 = { workspace = true, optional = true } spl-associated-token-account = { workspace = true, optional = true } thiserror.workspace = true +pinocchio.workspace = true +pinocchio-log.workspace = true +pinocchio-system.workspace = true +pinocchio-pubkey.workspace = true +pinocchio-associated-token-account.workspace = true +pinocchio-token.workspace = true +pinocchio-token-2022.workspace = true diff --git a/lib/src/account/close.rs b/lib/src/account/close.rs index af12b4b..8eb225b 100644 --- a/lib/src/account/close.rs +++ b/lib/src/account/close.rs @@ -1,20 +1,25 @@ -use solana_program::{account_info::AccountInfo, program_error::ProgramError, system_program}; +use solana_account_view::AccountView; +use solana_address::address; +use solana_program_error::ProgramError; -pub trait CloseAccount<'info> { - fn close(&self, to: &AccountInfo<'info>) -> Result<(), ProgramError>; +pub trait CloseAccount { + fn close(&self, to: &AccountView) -> Result<(), ProgramError>; } -impl<'info> CloseAccount<'info> for AccountInfo<'info> { - fn close(&self, to: &AccountInfo<'info>) -> Result<(), ProgramError> { +impl CloseAccount for AccountView { + fn close(&self, to: &AccountView) -> Result<(), ProgramError> { // Return rent lamports. - **to.lamports.borrow_mut() += self.lamports(); - **self.lamports.borrow_mut() = 0; + to.set_lamports(to.lamports() + self.lamports()); + self.set_lamports(0); // Assign system program as the owner - self.assign(&system_program::ID); + unsafe { + // self.assign(&system_program::ID); + self.assign(&address!("11111111111111111111111111111111")); + } // Realloc data to zero. - self.realloc(0, true)?; + self.resize(0)?; Ok(()) } diff --git a/lib/src/account/cpi.rs b/lib/src/account/cpi.rs index 2ebfba2..d351300 100644 --- a/lib/src/account/cpi.rs +++ b/lib/src/account/cpi.rs @@ -1,211 +1,155 @@ use bytemuck::Pod; -use solana_program::{ - account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, pubkey::Pubkey, - rent::Rent, sysvar::Sysvar, + +use pinocchio::cpi; +use pinocchio::sysvars::rent::Rent; +use pinocchio::sysvars::Sysvar; +use pinocchio::{ + cpi::{Seed, Signer}, + instruction::InstructionView, + AccountView, Address, ProgramResult, }; -use crate::{CloseAccount, Discriminator}; +// use crate::{CloseAccount}; +use crate::Discriminator; /// Invokes a CPI with provided signer seeds and program id. #[inline(always)] -pub fn invoke_signed<'info>( - instruction: &Instruction, - account_infos: &[AccountInfo<'info>], - program_id: &Pubkey, - seeds: &[&[u8]], +pub fn invoke_signed( + instruction: &InstructionView, + account_views: &[&AccountView; ACCOUNTS], + seeds: &[Seed; N], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, program_id).1; - invoke_signed_with_bump(instruction, account_infos, seeds, bump) -} + let signers_seeds = Signer::from(seeds); -/// Invokes a CPI with the provided signer seeds and bump. -#[inline(always)] -pub fn invoke_signed_with_bump<'info>( - instruction: &Instruction, - account_infos: &[AccountInfo<'info>], - seeds: &[&[u8]], - bump: u8, -) -> ProgramResult { - // Combine seeds - let bump: &[u8] = &[bump]; - let mut combined_seeds = Vec::with_capacity(seeds.len() + 1); - combined_seeds.extend_from_slice(seeds); - combined_seeds.push(bump); - let seeds = combined_seeds.as_slice(); - - // Invoke CPI - solana_program::program::invoke_signed(instruction, account_infos, &[seeds]) + cpi::invoke_signed(instruction, account_views, &[signers_seeds]) } /// Creates a new account. #[inline(always)] pub fn create_account<'a, 'info>( - from_pubkey: &'a AccountInfo<'info>, - to_pubkey: &'a AccountInfo<'info>, - system_program: &'a AccountInfo<'info>, + from: &'a AccountView, + to: &'a AccountView, space: usize, - owner: &Pubkey, + owner: &Address, ) -> ProgramResult { - let lamports_required = (Rent::get()?).minimum_balance(space); - - solana_program::program::invoke( - &solana_program::system_instruction::create_account( - from_pubkey.key, - to_pubkey.key, - lamports_required, - space as u64, - owner, - ), - &[ - from_pubkey.clone(), - to_pubkey.clone(), - system_program.clone(), - ], - )?; + let rent = Rent::get()?; + + let lamports_required = rent.try_minimum_balance(space)?; + + pinocchio_system::instructions::CreateAccount { + from, + to, + lamports: lamports_required, + space: space as u64, + owner, + } + .invoke()?; Ok(()) } /// Creates a new program account. #[inline(always)] -pub fn create_program_account<'a, 'info, T: Discriminator + Pod>( - target_account: &'a AccountInfo<'info>, - system_program: &'a AccountInfo<'info>, - payer: &'a AccountInfo<'info>, - owner: &Pubkey, - seeds: &[&[u8]], +pub fn create_program_account<'a, 'info, T: Discriminator + Pod, const N: usize>( + target_account: &'a AccountView, + payer: &'a AccountView, + owner: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - create_program_account_with_bump::( - target_account, - system_program, - payer, - owner, - seeds, - Pubkey::find_program_address(seeds, owner).1, - ) + create_program_account_with_bump::(target_account, payer, owner, seeds) } /// Creates a new program account with user-provided bump. #[inline(always)] -pub fn create_program_account_with_bump<'a, 'info, T: Discriminator + Pod>( - target_account: &'a AccountInfo<'info>, - system_program: &'a AccountInfo<'info>, - payer: &'a AccountInfo<'info>, - owner: &Pubkey, - seeds: &[&[u8]], - bump: u8, +pub fn create_program_account_with_bump<'a, 'info, T: Discriminator + Pod, const N: usize>( + target_account: &'a AccountView, + payer: &'a AccountView, + owner: &Address, + seeds: &[Seed; N], ) -> ProgramResult { // Allocate space. allocate_account_with_bump( target_account, - system_program, payer, 8 + std::mem::size_of::(), owner, seeds, - bump, )?; // Set discriminator. - let mut data = target_account.data.borrow_mut(); - data[0] = T::discriminator(); + let mut data = target_account.try_borrow_mut()?; + data.copy_from_slice(&T::discriminator().to_le_bytes()); Ok(()) } /// Allocates space for a new program account. #[inline(always)] -pub fn allocate_account<'a, 'info>( - target_account: &'a AccountInfo<'info>, - system_program: &'a AccountInfo<'info>, - payer: &'a AccountInfo<'info>, +pub fn allocate_account<'a, 'info, const N: usize>( + target_account: &'a AccountView, + payer: &'a AccountView, space: usize, - owner: &Pubkey, - seeds: &[&[u8]], + owner: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - allocate_account_with_bump( - target_account, - system_program, - payer, - space, - owner, - seeds, - Pubkey::find_program_address(seeds, owner).1, - ) + allocate_account_with_bump(target_account, payer, space, owner, seeds) } /// Allocates space for a new program account with user-provided bump. #[inline(always)] -pub fn allocate_account_with_bump<'a, 'info>( - target_account: &'a AccountInfo<'info>, - system_program: &'a AccountInfo<'info>, - payer: &'a AccountInfo<'info>, +pub fn allocate_account_with_bump<'a, 'info, const N: usize>( + target_account: &'a AccountView, + payer: &'a AccountView, space: usize, - owner: &Pubkey, - seeds: &[&[u8]], - bump: u8, + owner: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - // Combine seeds - let bump: &[u8] = &[bump]; - let mut combined_seeds = Vec::with_capacity(seeds.len() + 1); - combined_seeds.extend_from_slice(seeds); - combined_seeds.push(bump); - let seeds = combined_seeds.as_slice(); + let signer_seeds = Signer::from(seeds); // Allocate space for account let rent = Rent::get()?; + if target_account.lamports().eq(&0) { // If balance is zero, create account - solana_program::program::invoke_signed( - &solana_program::system_instruction::create_account( - payer.key, - target_account.key, - rent.minimum_balance(space), - space as u64, - owner, - ), - &[ - payer.clone(), - target_account.clone(), - system_program.clone(), - ], - &[seeds], - )?; + + pinocchio_system::instructions::CreateAccount { + from: payer, + to: target_account, + lamports: rent.try_minimum_balance(space)?, + space: space as u64, + owner, + } + .invoke_signed(&[signer_seeds.clone()])?; } else { // Otherwise, if balance is nonzero: // 1) transfer sufficient lamports for rent exemption let rent_exempt_balance = rent - .minimum_balance(space) + .try_minimum_balance(space)? .saturating_sub(target_account.lamports()); if rent_exempt_balance.gt(&0) { - solana_program::program::invoke( - &solana_program::system_instruction::transfer( - payer.key, - target_account.key, - rent_exempt_balance, - ), - &[ - payer.clone(), - target_account.clone(), - system_program.clone(), - ], - )?; + pinocchio_system::instructions::Transfer { + from: payer, + to: target_account, + lamports: rent_exempt_balance, + } + .invoke()?; } // 2) allocate space for the account - solana_program::program::invoke_signed( - &solana_program::system_instruction::allocate(target_account.key, space as u64), - &[target_account.clone(), system_program.clone()], - &[seeds], - )?; + + pinocchio_system::instructions::Allocate { + account: target_account, + space: space as u64, + } + .invoke_signed(&[signer_seeds.clone()])?; // 3) assign our program as the owner - solana_program::program::invoke_signed( - &solana_program::system_instruction::assign(target_account.key, owner), - &[target_account.clone(), system_program.clone()], - &[seeds], - )?; + pinocchio_system::instructions::Assign { + account: target_account, + owner, + } + .invoke_signed(&[signer_seeds])?; } Ok(()) @@ -213,9 +157,11 @@ pub fn allocate_account_with_bump<'a, 'info>( /// Closes an account and returns the remaining rent lamports to the provided recipient. #[inline(always)] -pub fn close_account<'info>( - account_info: &AccountInfo<'info>, - recipient: &AccountInfo<'info>, -) -> ProgramResult { - account_info.close(recipient) +pub fn close_account(account_info: &AccountView, recipient: &AccountView) -> ProgramResult { + let lamports = account_info.lamports(); + + account_info.set_lamports(lamports - lamports); + recipient.set_lamports(recipient.lamports() + lamports); + + account_info.close() } diff --git a/lib/src/account/deserialize.rs b/lib/src/account/deserialize.rs index 59f928d..511213a 100644 --- a/lib/src/account/deserialize.rs +++ b/lib/src/account/deserialize.rs @@ -1,6 +1,5 @@ use bytemuck::Pod; -use solana_program::program_error::ProgramError; - +use pinocchio::error::ProgramError; pub trait Discriminator { fn discriminator() -> u8; } @@ -16,20 +15,17 @@ where { fn try_from_bytes(data: &[u8]) -> Result<&Self, ProgramError> { if Self::discriminator().ne(&data[0]) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); + return Err(ProgramError::InvalidAccountData); } - bytemuck::try_from_bytes::(&data[8..]).or(Err( - solana_program::program_error::ProgramError::InvalidAccountData, - )) + bytemuck::try_from_bytes::(&data[8..]).or(Err(ProgramError::InvalidAccountData)) } fn try_from_bytes_mut(data: &mut [u8]) -> Result<&mut Self, ProgramError> { if Self::discriminator().ne(&data[0]) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); + return Err(ProgramError::InvalidAccountData); } - bytemuck::try_from_bytes_mut::(&mut data[8..]).or(Err( - solana_program::program_error::ProgramError::InvalidAccountData, - )) + bytemuck::try_from_bytes_mut::(&mut data[8..]) + .or(Err(ProgramError::InvalidAccountData)) } } @@ -50,13 +46,11 @@ where { fn try_header_from_bytes(data: &[u8]) -> Result<(&Self, &[u8]), ProgramError> { if Self::discriminator().ne(&data[0]) { - return Err(solana_program::program_error::ProgramError::InvalidAccountData); + return Err(ProgramError::InvalidAccountData); } let (prefix, remainder) = data[8..].split_at(std::mem::size_of::()); Ok(( - bytemuck::try_from_bytes::(prefix).or(Err( - solana_program::program_error::ProgramError::InvalidAccountData, - ))?, + bytemuck::try_from_bytes::(prefix).or(Err(ProgramError::InvalidAccountData))?, remainder, )) } @@ -64,9 +58,8 @@ where fn try_header_from_bytes_mut(data: &mut [u8]) -> Result<(&mut Self, &mut [u8]), ProgramError> { let (prefix, remainder) = data[8..].split_at_mut(std::mem::size_of::()); Ok(( - bytemuck::try_from_bytes_mut::(prefix).or(Err( - solana_program::program_error::ProgramError::InvalidAccountData, - ))?, + bytemuck::try_from_bytes_mut::(prefix) + .or(Err(ProgramError::InvalidAccountData))?, remainder, )) } diff --git a/lib/src/account/lamports.rs b/lib/src/account/lamports.rs index a7e5a27..1eba36b 100644 --- a/lib/src/account/lamports.rs +++ b/lib/src/account/lamports.rs @@ -1,22 +1,25 @@ -use solana_program::{account_info::AccountInfo, program_error::ProgramError}; +use pinocchio::{error::ProgramError, AccountView}; +use pinocchio_system::instructions::Transfer; -pub trait LamportTransfer<'a, 'info> { - fn send(&'a self, lamports: u64, to: &'a AccountInfo<'info>); - fn collect(&'a self, lamports: u64, from: &'a AccountInfo<'info>) -> Result<(), ProgramError>; +pub trait LamportTransfer { + fn send(&self, lamports: u64, to: &AccountView); + fn collect(&self, lamports: u64, from: &AccountView) -> Result<(), ProgramError>; } -impl<'a, 'info> LamportTransfer<'a, 'info> for AccountInfo<'info> { +impl LamportTransfer for AccountView { #[inline(always)] - fn send(&'a self, lamports: u64, to: &'a AccountInfo<'info>) { - **self.lamports.borrow_mut() -= lamports; - **to.lamports.borrow_mut() += lamports; + fn send(&self, lamports: u64, to: &AccountView) { + self.set_lamports(self.lamports() - lamports); + to.set_lamports(to.lamports() + lamports); } #[inline(always)] - fn collect(&'a self, lamports: u64, from: &'a AccountInfo<'info>) -> Result<(), ProgramError> { - solana_program::program::invoke( - &solana_program::system_instruction::transfer(from.key, self.key, lamports), - &[from.clone(), self.clone()], - ) + fn collect(&self, lamports: u64, from: &AccountView) -> Result<(), ProgramError> { + Transfer { + from, + to: &self, + lamports, + } + .invoke() } } diff --git a/lib/src/account/validation.rs b/lib/src/account/validation.rs index 75ec5c1..7367191 100644 --- a/lib/src/account/validation.rs +++ b/lib/src/account/validation.rs @@ -1,27 +1,35 @@ use bytemuck::Pod; -use solana_program::{account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey}; +use solana_account_view::AccountView; +use solana_address::Address; +use solana_program_error::ProgramError; use crate::trace; use super::{AccountDeserialize, Discriminator}; +/// `Sysvar1111111111111111111111111111111111111` +pub const SYSVAR_ID: Address = Address::new_from_array([ + 6, 167, 213, 23, 24, 117, 247, 41, 199, 61, 147, 64, 143, 33, 97, 32, 6, 126, 216, 140, 118, + 224, 140, 40, 127, 193, 148, 96, 0, 0, 0, 0, +]); + pub trait AccountInfoValidation { fn is_signer(&self) -> Result<&Self, ProgramError>; fn is_writable(&self) -> Result<&Self, ProgramError>; fn is_executable(&self) -> Result<&Self, ProgramError>; fn is_empty(&self) -> Result<&Self, ProgramError>; - fn is_type(&self, program_id: &Pubkey) -> Result<&Self, ProgramError>; - fn is_program(&self, program_id: &Pubkey) -> Result<&Self, ProgramError>; - fn is_sysvar(&self, sysvar_id: &Pubkey) -> Result<&Self, ProgramError>; - fn has_address(&self, address: &Pubkey) -> Result<&Self, ProgramError>; - fn has_owner(&self, program_id: &Pubkey) -> Result<&Self, ProgramError>; - fn has_seeds(&self, seeds: &[&[u8]], program_id: &Pubkey) -> Result<&Self, ProgramError>; + fn is_type(&self, program_id: &Address) -> Result<&Self, ProgramError>; + fn is_program(&self, program_id: &Address) -> Result<&Self, ProgramError>; + fn is_sysvar(&self, sysvar_id: &Address) -> Result<&Self, ProgramError>; + fn has_address(&self, address: &Address) -> Result<&Self, ProgramError>; + fn has_owner(&self, program_id: &Address) -> Result<&Self, ProgramError>; + fn has_seeds(&self, seeds: &[&[u8]], program_id: &Address) -> Result<&Self, ProgramError>; } -impl AccountInfoValidation for AccountInfo<'_> { +impl AccountInfoValidation for AccountView { #[track_caller] fn is_empty(&self) -> Result<&Self, ProgramError> { - if !self.data_is_empty() { + if !self.is_data_empty() { return Err(trace( "Account already initialized", ProgramError::AccountAlreadyInitialized, @@ -32,7 +40,7 @@ impl AccountInfoValidation for AccountInfo<'_> { #[track_caller] fn is_executable(&self) -> Result<&Self, ProgramError> { - if !self.executable { + if !self.executable() { return Err(trace( "Account is not executable", ProgramError::InvalidAccountData, @@ -42,13 +50,13 @@ impl AccountInfoValidation for AccountInfo<'_> { } #[track_caller] - fn is_program(&self, program_id: &Pubkey) -> Result<&Self, ProgramError> { + fn is_program(&self, program_id: &Address) -> Result<&Self, ProgramError> { self.has_address(program_id)?.is_executable() } #[track_caller] fn is_signer(&self) -> Result<&Self, ProgramError> { - if !self.is_signer { + if !self.is_signer() { return Err(trace( "Account is not a signer", ProgramError::MissingRequiredSignature, @@ -58,15 +66,14 @@ impl AccountInfoValidation for AccountInfo<'_> { } #[track_caller] - fn is_sysvar(&self, sysvar_id: &Pubkey) -> Result<&Self, ProgramError> { - self.has_owner(&solana_program::sysvar::ID)? - .has_address(sysvar_id) + fn is_sysvar(&self, sysvar_id: &Address) -> Result<&Self, ProgramError> { + self.has_owner(&SYSVAR_ID)?.has_address(sysvar_id) } #[track_caller] - fn is_type(&self, program_id: &Pubkey) -> Result<&Self, ProgramError> { + fn is_type(&self, program_id: &Address) -> Result<&Self, ProgramError> { self.has_owner(program_id)?; - if self.try_borrow_data()?[0].ne(&T::discriminator()) { + if unsafe { self.borrow_unchecked()[0] }.ne(&T::discriminator()) { return Err(trace( format!("Account is not of type {}", T::discriminator()).as_str(), ProgramError::InvalidAccountData, @@ -77,7 +84,7 @@ impl AccountInfoValidation for AccountInfo<'_> { #[track_caller] fn is_writable(&self) -> Result<&Self, ProgramError> { - if !self.is_writable { + if !self.is_writable() { return Err(trace( "Account is not writable", ProgramError::MissingRequiredSignature, @@ -87,10 +94,15 @@ impl AccountInfoValidation for AccountInfo<'_> { } #[track_caller] - fn has_address(&self, address: &Pubkey) -> Result<&Self, ProgramError> { - if self.key.ne(&address) { + fn has_address(&self, address: &Address) -> Result<&Self, ProgramError> { + if self.address().ne(address) { return Err(trace( - format!("Account has invalid address {} != {}", self.key, address).as_str(), + format!( + "Account has invalid address {} != {}", + self.address(), + address + ) + .as_str(), ProgramError::InvalidAccountData, )); } @@ -98,22 +110,28 @@ impl AccountInfoValidation for AccountInfo<'_> { } #[track_caller] - fn has_owner(&self, owner: &Pubkey) -> Result<&Self, ProgramError> { - if self.owner.ne(owner) { + fn has_owner(&self, owner: &Address) -> Result<&Self, ProgramError> { + if self.owned_by(owner) { return Err(trace( - format!("Account has invalid owner {} != {}", self.owner, owner).as_str(), + format!( + "Account has invalid owner {} != {}", + unsafe { self.owner() }, + owner + ) + .as_str(), ProgramError::InvalidAccountOwner, )); } + Ok(self) } #[track_caller] - fn has_seeds(&self, seeds: &[&[u8]], program_id: &Pubkey) -> Result<&Self, ProgramError> { - let pda = Pubkey::find_program_address(seeds, program_id); - if self.key.ne(&pda.0) { + fn has_seeds(&self, seeds: &[&[u8]], program_id: &Address) -> Result<&Self, ProgramError> { + let pda = Address::find_program_address(seeds, program_id); + if self.address().ne(&pda.0) { return Err(trace( - format!("Account has invalid seeds {} != {}", self.key, pda.0).as_str(), + format!("Account has invalid seeds {} != {}", self.address(), pda.0).as_str(), ProgramError::InvalidSeeds, )); } @@ -126,18 +144,18 @@ impl AccountInfoValidation for AccountInfo<'_> { /// 2. Discriminator byte check /// 3. Checked bytemuck conversion of account data to &T or &mut T. pub trait AsAccount { - fn as_account(&self, program_id: &Pubkey) -> Result<&T, ProgramError> + fn as_account(&self, program_id: &Address) -> Result<&T, ProgramError> where T: AccountDeserialize + Discriminator + Pod; - fn as_account_mut(&self, program_id: &Pubkey) -> Result<&mut T, ProgramError> + fn as_account_mut(&self, program_id: &Address) -> Result<&mut T, ProgramError> where T: AccountDeserialize + Discriminator + Pod; } -impl AsAccount for AccountInfo<'_> { +impl AsAccount for AccountView { #[track_caller] - fn as_account(&self, program_id: &Pubkey) -> Result<&T, ProgramError> + fn as_account(&self, program_id: &Address) -> Result<&T, ProgramError> where T: AccountDeserialize + Discriminator + Pod, { @@ -146,7 +164,7 @@ impl AsAccount for AccountInfo<'_> { self.has_owner(program_id)?; // Validate account data length. - let data = self.try_borrow_data()?; + let data = self.borrow_unchecked(); let expected_len = 8 + std::mem::size_of::(); if data.len() != expected_len { return Err(trace( @@ -166,7 +184,7 @@ impl AsAccount for AccountInfo<'_> { } #[track_caller] - fn as_account_mut(&self, program_id: &Pubkey) -> Result<&mut T, ProgramError> + fn as_account_mut(&self, program_id: &Address) -> Result<&mut T, ProgramError> where T: AccountDeserialize + Discriminator + Pod, { @@ -175,7 +193,7 @@ impl AsAccount for AccountInfo<'_> { self.has_owner(program_id)?; // Validate account data length. - let mut data = self.try_borrow_mut_data()?; + let data = self.borrow_unchecked_mut(); let expected_len = 8 + std::mem::size_of::(); if data.len() != expected_len { return Err(trace( diff --git a/lib/src/lib.rs b/lib/src/lib.rs index 31acc27..318a409 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -1,29 +1,40 @@ mod account; mod log; -pub mod macros; +// pub mod macros; mod numeric; #[cfg(feature = "spl")] mod spl; -mod utils; +// mod utils; pub use account::*; pub use log::*; pub use numeric::*; #[cfg(feature = "spl")] pub use spl::*; -pub use utils::*; +// pub use utils::*; pub use bytemuck::{Pod, Zeroable}; -pub use num_enum::{IntoPrimitive, TryFromPrimitive}; -pub use solana_program::{ - account_info::AccountInfo, - clock::Clock, - declare_id, entrypoint, - entrypoint::ProgramResult, - instruction::{AccountMeta, Instruction}, - program_error::ProgramError, - pubkey::Pubkey, - system_program, sysvar, - sysvar::Sysvar, -}; +// pub use num_enum::{IntoPrimitive, TryFromPrimitive}; +// pub use solana_account_view::AccountView; +// pub use solana_address::{address, Address}; +// pub use solana_instruction_view::InstructionView; +// pub use solana_program_error::{ProgramError, ProgramResult}; + +// use solana_clock::Clock; +// use solana_declare_id::declare_id; +// use solana_entrypoint::entrypoint; +// use solana_entrypoint::ProgramResult; +// use solana_instruction::Instruction; + +// pub use solana_program::{ +// account_info::AccountInfo, +// clock::Clock, +// declare_id, entrypoint, +// entrypoint::ProgramResult, +// instruction::{AccountMeta, Instruction}, +// program_error::ProgramError, +// pubkey::Pubkey, +// system_program, sysvar, +// sysvar::Sysvar, +// }; pub use thiserror::Error; diff --git a/lib/src/log.rs b/lib/src/log.rs index 45326ef..6b57568 100644 --- a/lib/src/log.rs +++ b/lib/src/log.rs @@ -1,16 +1,17 @@ -use solana_program::program_error::ProgramError; +use pinocchio::error::ProgramError; +use pinocchio_log::log; /// Logs a message. #[inline(always)] -pub fn log(msg: String) { - solana_program::log::sol_log(msg.as_str()); +pub fn log(msg: &str) { + log!("{}", msg); } /// Logs the call trace and returns the error. #[track_caller] pub fn trace(msg: &str, error: ProgramError) -> ProgramError { let caller = std::panic::Location::caller(); - log(format!("{}: {}", msg, caller)); + log(&format!("{}: {}", msg, caller)); error } diff --git a/lib/src/spl/cpi.rs b/lib/src/spl/cpi.rs index d753f83..da6656d 100644 --- a/lib/src/spl/cpi.rs +++ b/lib/src/spl/cpi.rs @@ -1,1164 +1,551 @@ -use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey}; - -use crate::account::invoke_signed_with_bump; - -#[inline(always)] -pub fn create_associated_token_account<'info>( - funder_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - system_program: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - associated_token_program: &AccountInfo<'info>, -) -> ProgramResult { - solana_program::program::invoke( - &spl_associated_token_account::instruction::create_associated_token_account( - funder_info.key, - owner_info.key, - mint_info.key, - &token_program.key, - ), - &[ - funder_info.clone(), - token_account_info.clone(), - owner_info.clone(), - mint_info.clone(), - system_program.clone(), - token_program.clone(), - associated_token_program.clone(), - ], - ) -} - -#[inline(always)] -pub fn close_token_account<'info>( - account_info: &AccountInfo<'info>, - destination_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::close_account( - &token_program.key, - &account_info.key, - &destination_info.key, - &owner_info.key, - &[&owner_info.key], - )?, - &[ - token_program.clone(), - account_info.clone(), - destination_info.clone(), - owner_info.clone(), - ], - ) -} - -#[inline(always)] -pub fn close_token_account_signed<'info>( - account_info: &AccountInfo<'info>, - destination_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], -) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, owner_info.owner).1; - close_token_account_signed_with_bump( - account_info, - destination_info, - owner_info, +use pinocchio::{ + cpi::{Seed, Signer}, + AccountView, Address, ProgramResult, +}; + +#[inline(always)] +pub fn create_associated_token_account( + funder_info: &AccountView, + owner_info: &AccountView, + token_account_info: &AccountView, + mint_info: &AccountView, + system_program: &AccountView, + token_program: &AccountView, +) -> ProgramResult { + pinocchio_associated_token_account::instructions::Create { + funding_account: funder_info, + account: token_account_info, + wallet: owner_info, + mint: mint_info, + system_program, token_program, - seeds, - bump, - ) + } + .invoke() } +// TODO: why is this using token 2022? #[inline(always)] -pub fn close_token_account_signed_with_bump<'info>( - account_info: &AccountInfo<'info>, - destination_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], - bump: u8, +pub fn close_token_account( + account_info: &AccountView, + destination_info: &AccountView, + owner_info: &AccountView, + token_program: &Address, ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::close_account( - &token_program.key, - &account_info.key, - &destination_info.key, - &owner_info.key, - &[&owner_info.key], - )?, - &[ - token_program.clone(), - account_info.clone(), - destination_info.clone(), - owner_info.clone(), - ], - seeds, - bump, - ) + pinocchio_token_2022::instructions::CloseAccount { + account: account_info, + destination: destination_info, + authority: owner_info, + token_program: token_program, + } + .invoke() } #[inline(always)] -pub fn transfer<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, +pub fn close_token_account_signed( + account_info: &AccountView, + destination_info: &AccountView, + owner_info: &AccountView, + token_program: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - #[allow(deprecated)] - solana_program::program::invoke( - &spl_token_2022::instruction::transfer( - &token_program.key, - from_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - from_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn transfer_signed<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, - seeds: &[&[u8]], -) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - transfer_signed_with_bump( - authority_info, - from_info, - to_info, - token_program, - amount, - seeds, - bump, - ) + pinocchio_token_2022::instructions::CloseAccount { + account: account_info, + destination: destination_info, + authority: owner_info, + token_program: token_program, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn transfer_signed_with_bump<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn transfer( + authority_info: &AccountView, + from_info: &AccountView, + to_info: &AccountView, + token_program: &Address, amount: u64, - seeds: &[&[u8]], - bump: u8, ) -> ProgramResult { - #[allow(deprecated)] - invoke_signed_with_bump( - &spl_token_2022::instruction::transfer( - &token_program.key, - from_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - from_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - seeds, - bump, - ) + pinocchio_token_2022::instructions::Transfer { + from: from_info, + to: to_info, + authority: authority_info, + amount: amount, + token_program: token_program, + } + .invoke() } #[inline(always)] -pub fn transfer_checked<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn transfer_signed( + authority_info: &AccountView, + from_info: &AccountView, + to_info: &AccountView, + token_program: &Address, amount: u64, - decimals: u8, + seeds: &[Seed; N], ) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::transfer_checked( - &token_program.key, - from_info.key, - mint_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - decimals, - )?, - &[ - token_program.clone(), - from_info.clone(), - mint_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - ) + let signer_seeds = Signer::from(seeds); + + pinocchio_token_2022::instructions::Transfer { + from: from_info, + to: to_info, + authority: authority_info, + amount: amount, + token_program: token_program, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn transfer_checked_signed<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn transfer_checked( + authority_info: &AccountView, + from_info: &AccountView, + mint_info: &AccountView, + to_info: &AccountView, + token_program: &Address, amount: u64, decimals: u8, - seeds: &[&[u8]], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - transfer_checked_signed_with_bump( - authority_info, - from_info, - mint_info, - to_info, - token_program, + pinocchio_token_2022::instructions::TransferChecked { + from: from_info, + mint: mint_info, + to: to_info, + token_program: token_program, + authority: authority_info, amount, decimals, - seeds, - bump, - ) + } + .invoke() } #[inline(always)] -pub fn transfer_checked_signed_with_bump<'info>( - authority_info: &AccountInfo<'info>, - from_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn transfer_checked_signed( + authority_info: &AccountView, + from_info: &AccountView, + mint_info: &AccountView, + to_info: &AccountView, + token_program: &Address, amount: u64, decimals: u8, - seeds: &[&[u8]], - bump: u8, + seeds: &[Seed; N], ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::transfer_checked( - &token_program.key, - from_info.key, - mint_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - decimals, - )?, - &[ - token_program.clone(), - from_info.clone(), - mint_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - seeds, - bump, - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn mint_to_signed<'info>( - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, - seeds: &[&[u8]], -) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - mint_to_signed_with_bump( - mint_info, - to_info, - authority_info, - token_program, + pinocchio_token_2022::instructions::TransferChecked { + from: from_info, + mint: mint_info, + to: to_info, + token_program: token_program, + authority: authority_info, amount, - seeds, - bump, - ) + decimals, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn mint_to_signed_with_bump<'info>( - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn mint_to_signed( + mint_info: &AccountView, + to_info: &AccountView, + authority_info: &AccountView, amount: u64, - seeds: &[&[u8]], - bump: u8, + seeds: &[Seed; N], ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::mint_to( - &token_program.key, - 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(), - ], - seeds, - bump, - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn mint_to_checked_signed<'info>( - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, - decimals: u8, - seeds: &[&[u8]], -) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - mint_to_checked_signed_with_bump( - mint_info, - to_info, - authority_info, - token_program, + pinocchio_token::instructions::MintTo { + mint: mint_info, + account: to_info, + mint_authority: authority_info, amount, - decimals, - seeds, - bump, - ) + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn mint_to_checked_signed_with_bump<'info>( - mint_info: &AccountInfo<'info>, - to_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn mint_to_checked_signed( + mint_info: &AccountView, + to_info: &AccountView, + authority_info: &AccountView, amount: u64, decimals: u8, - seeds: &[&[u8]], - bump: u8, + seeds: &[Seed; N], ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::mint_to_checked( - &token_program.key, - mint_info.key, - to_info.key, - authority_info.key, - &[authority_info.key], - amount, - decimals, - )?, - &[ - token_program.clone(), - mint_info.clone(), - to_info.clone(), - authority_info.clone(), - ], - seeds, - bump, - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn burn<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::burn( - &token_program.key, - token_account_info.key, - mint_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - token_account_info.clone(), - mint_info.clone(), - authority_info.clone(), - ], - ) + pinocchio_token::instructions::MintToChecked { + mint: mint_info, + account: to_info, + mint_authority: authority_info, + amount, + decimals, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn burn_signed<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn burn( + token_account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, - seeds: &[&[u8]], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - burn_signed_with_bump( - token_account_info, - mint_info, - authority_info, - token_program, + pinocchio_token_2022::instructions::Burn { + account: token_account_info, + mint: mint_info, + authority: authority_info, amount, - seeds, - bump, - ) + token_program, + } + .invoke() } #[inline(always)] -pub fn burn_signed_with_bump<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn burn_signed( + token_account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, - seeds: &[&[u8]], - bump: u8, + seeds: &[Seed; N], ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::burn( - &token_program.key, - token_account_info.key, - mint_info.key, - authority_info.key, - &[authority_info.key], - amount, - )?, - &[ - token_program.clone(), - token_account_info.clone(), - mint_info.clone(), - authority_info.clone(), - ], - seeds, - bump, - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn burn_checked<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, - decimals: u8, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::burn_checked( - &token_program.key, - token_account_info.key, - mint_info.key, - authority_info.key, - &[authority_info.key], - amount, - decimals, - )?, - &[ - token_program.clone(), - token_account_info.clone(), - mint_info.clone(), - authority_info.clone(), - ], - ) + pinocchio_token_2022::instructions::Burn { + account: token_account_info, + mint: mint_info, + authority: authority_info, + amount, + token_program, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn burn_checked_signed<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn burn_checked( + token_account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, decimals: u8, - seeds: &[&[u8]], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - burn_checked_signed_with_bump( - token_account_info, - mint_info, - authority_info, - token_program, + pinocchio_token_2022::instructions::BurnChecked { + account: token_account_info, + mint: mint_info, + authority: authority_info, amount, decimals, - seeds, - bump, - ) + token_program, + } + .invoke() } #[inline(always)] -pub fn burn_checked_signed_with_bump<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn burn_checked_signed( + token_account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, decimals: u8, - seeds: &[&[u8]], - bump: u8, + seeds: &[Seed; N], ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::burn_checked( - &token_program.key, - token_account_info.key, - mint_info.key, - authority_info.key, - &[authority_info.key], - amount, - decimals, - )?, - &[ - token_program.clone(), - token_account_info.clone(), - mint_info.clone(), - authority_info.clone(), - ], - seeds, - bump, - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn freeze<'info>( - account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::freeze_account( - &token_program.key, - account_info.key, - mint_info.key, - owner_info.key, - &[signer_info.key], - )?, - &[ - token_program.clone(), - account_info.clone(), - mint_info.clone(), - owner_info.clone(), - signer_info.clone(), - ], - ) + pinocchio_token_2022::instructions::BurnChecked { + account: token_account_info, + mint: mint_info, + authority: authority_info, + amount, + decimals, + token_program, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn freeze_signed<'info>( - account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], +pub fn freeze( + account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, signer_info.owner).1; - freeze_signed_with_bump( - account_info, - mint_info, - owner_info, - signer_info, + pinocchio_token_2022::instructions::FreezeAccount { + account: account_info, + mint: mint_info, + freeze_authority: authority_info, token_program, - seeds, - bump, - ) + } + .invoke() } #[inline(always)] -pub fn freeze_signed_with_bump<'info>( - account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], - bump: u8, +pub fn freeze_signed( + account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::freeze_account( - &token_program.key, - account_info.key, - mint_info.key, - owner_info.key, - &[signer_info.key], - )?, - &[ - token_program.clone(), - account_info.clone(), - mint_info.clone(), - owner_info.clone(), - signer_info.clone(), - ], - seeds, - bump, - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn initialize_mint<'info>( - mint_info: &AccountInfo<'info>, - mint_authority_info: &AccountInfo<'info>, - freeze_authority_info: Option<&AccountInfo<'info>>, - token_program: &AccountInfo<'info>, - rent_sysvar: &AccountInfo<'info>, - decimals: u8, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::initialize_mint( - &token_program.key, - mint_info.key, - mint_authority_info.key, - freeze_authority_info.map(|i| i.key), - decimals, - )?, - &[ - token_program.clone(), - mint_info.clone(), - mint_authority_info.clone(), - rent_sysvar.clone(), - ], - ) + pinocchio_token_2022::instructions::FreezeAccount { + account: account_info, + mint: mint_info, + freeze_authority: authority_info, + token_program, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn initialize_mint_signed<'info>( - mint_info: &AccountInfo<'info>, - mint_authority_info: &AccountInfo<'info>, - freeze_authority_info: Option<&AccountInfo<'info>>, - token_program: &AccountInfo<'info>, - rent_sysvar: &AccountInfo<'info>, +pub fn initialize_mint( + mint_info: &AccountView, + rent_sysvar: &AccountView, + mint_authority: &Address, + freeze_authority: Option<&Address>, + token_program: &Address, decimals: u8, - seeds: &[&[u8]], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, mint_info.owner).1; - initialize_mint_signed_with_bump( - mint_info, - mint_authority_info, - freeze_authority_info, - token_program, + pinocchio_token_2022::instructions::InitializeMint { + mint: mint_info, rent_sysvar, decimals, - seeds, - bump, - ) -} - -#[inline(always)] -pub fn initialize_mint_signed_with_bump<'info>( - mint_info: &AccountInfo<'info>, - mint_authority_info: &AccountInfo<'info>, - freeze_authority_info: Option<&AccountInfo<'info>>, - token_program: &AccountInfo<'info>, - rent_sysvar: &AccountInfo<'info>, - decimals: u8, - seeds: &[&[u8]], - bump: u8, -) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::initialize_mint( - &token_program.key, - mint_info.key, - mint_authority_info.key, - freeze_authority_info.map(|i| i.key), - decimals, - )?, - &[ - token_program.clone(), - mint_info.clone(), - mint_authority_info.clone(), - rent_sysvar.clone(), - ], - seeds, - bump, - ) + mint_authority, + freeze_authority, + token_program, + } + .invoke() } /// Thaws a frozen SPL token account -/// #[inline(always)] -pub fn thaw_account<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn thaw_account( + token_account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, ) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::thaw_account( - &token_program.key, - token_account_info.key, - mint_info.key, - authority_info.key, - &[authority_info.key], - )?, - &[ - token_program.clone(), - token_account_info.clone(), - mint_info.clone(), - authority_info.clone(), - ], - ) + pinocchio_token_2022::instructions::ThawAccount { + account: token_account_info, + mint: mint_info, + freeze_authority: authority_info, + token_program, + } + .invoke() } /// Thaws a frozen SPL token account using signed account -/// #[inline(always)] -pub fn thaw_account_signed<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], +pub fn thaw_account_signed( + token_account_info: &AccountView, + mint_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - thaw_account_signed_with_bump( - token_account_info, - mint_info, - owner_info, - authority_info, - token_program, - seeds, - bump, - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn thaw_account_signed_with_bump<'info>( - token_account_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], - bump: u8, -) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::thaw_account( - &token_program.key, - token_account_info.key, - mint_info.key, - owner_info.key, - &[signer_info.key], - )?, - &[ - token_program.clone(), - token_account_info.clone(), - mint_info.clone(), - owner_info.clone(), - signer_info.clone(), - ], - seeds, - bump, - ) + pinocchio_token_2022::instructions::ThawAccount { + account: token_account_info, + mint: mint_info, + freeze_authority: authority_info, + token_program, + } + .invoke_signed(&[signer_seeds]) } /// Set authority for an SPL token mint -/// #[inline(always)] -pub fn set_authority<'info>( - account_or_mint: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - new_authority_info: Option<&AccountInfo<'info>>, - authority_type: spl_token_2022::instruction::AuthorityType, - token_program: &AccountInfo<'info>, +pub fn set_authority( + account_or_mint: &AccountView, + authority_info: &AccountView, + new_authority: Option<&Address>, + authority_type: pinocchio_token_2022::instructions::AuthorityType, + token_program: &Address, ) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::set_authority( - &token_program.key, - account_or_mint.key, - new_authority_info.map(|i| i.key), - authority_type, - authority_info.key, - &[authority_info.key], - )?, - &[ - token_program.clone(), - account_or_mint.clone(), - authority_info.clone(), - ], - ) + pinocchio_token_2022::instructions::SetAuthority { + account: account_or_mint, + authority: authority_info, + authority_type, + new_authority, + token_program, + } + .invoke() } /// Set authority using signer seeds -/// #[inline(always)] -pub fn set_authority_signed<'info>( - account_or_mint: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - new_authority_info: Option<&AccountInfo<'info>>, - authority_type: spl_token_2022::instruction::AuthorityType, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], +pub fn set_authority_signed( + account_or_mint: &AccountView, + authority_info: &AccountView, + new_authority: Option<&Address>, + authority_type: pinocchio_token_2022::instructions::AuthorityType, + token_program: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - set_authority_signed_with_bump( - account_or_mint, - authority_info, - new_authority_info, + let signer_seeds = Signer::from(seeds); + + pinocchio_token_2022::instructions::SetAuthority { + account: account_or_mint, + authority: authority_info, authority_type, + new_authority, token_program, - seeds, - bump, - ) -} - -#[inline(always)] -pub fn set_authority_signed_with_bump<'info>( - account_or_mint: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - new_authority_info: Option<&AccountInfo<'info>>, - authority_type: spl_token_2022::instruction::AuthorityType, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], - bump: u8, -) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::set_authority( - &token_program.key, - account_or_mint.key, - new_authority_info.map(|i| i.key), - authority_type, - authority_info.key, - &[authority_info.key], - )?, - &[ - token_program.clone(), - account_or_mint.clone(), - authority_info.clone(), - ], - seeds, - bump, - ) + } + .invoke_signed(&[signer_seeds]) } /// Revoke -/// #[inline(always)] -pub fn revoke<'info>( - source_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn revoke( + source_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, ) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::revoke( - &token_program.key, - source_info.key, - authority_info.key, - &[authority_info.key], - )?, - &[ - token_program.clone(), - source_info.clone(), - authority_info.clone(), - ], - ) + pinocchio_token_2022::instructions::Revoke { + source: source_info, + authority: authority_info, + token_program, + } + .invoke() } /// Revoke with signer seeds -/// #[inline(always)] -pub fn revoke_signed<'info>( - source_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], +pub fn revoke_signed( + source_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, + seeds: &[Seed; N], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, authority_info.owner).1; - revoke_signed_with_bump(source_info, authority_info, token_program, seeds, bump) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn revoke_signed_with_bump<'info>( - source_info: &AccountInfo<'info>, - authority_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - seeds: &[&[u8]], - bump: u8, -) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::revoke( - &token_program.key, - source_info.key, - authority_info.key, - &[authority_info.key], - )?, - &[ - token_program.clone(), - source_info.clone(), - authority_info.clone(), - ], - seeds, - bump, - ) + pinocchio_token_2022::instructions::Revoke { + source: source_info, + authority: authority_info, + token_program, + } + .invoke_signed(&[signer_seeds]) } -/// /// Approves a delegate. A delegate is given the authority over tokens on +/// Approves a delegate. A delegate is given the authority over tokens on /// behalf of the source account's owner. #[inline(always)] -pub fn approve<'info>( - source_info: &AccountInfo<'info>, - delegate_info: &AccountInfo<'info>, - owner_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn approve( + source_info: &AccountView, + delegate_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, ) -> ProgramResult { - solana_program::program::invoke( - &spl_token::instruction::approve( - &spl_token::ID, - source_info.key, - delegate_info.key, - owner_info.key, - &[signer_info.key], - amount, - )?, - &[ - token_program.clone(), - source_info.clone(), - delegate_info.clone(), - owner_info.clone(), - signer_info.clone(), - ], - ) + pinocchio_token_2022::instructions::Approve { + source: source_info, + delegate: delegate_info, + authority: authority_info, + amount, + token_program, + } + .invoke() } #[inline(always)] -pub fn approve_signed<'info>( - source_info: &AccountInfo<'info>, - delegate_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn approve_signed( + source_info: &AccountView, + delegate_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, - seeds: &[&[u8]], + seeds: &[Seed; N], ) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, &spl_token::ID).1; - approve_signed_with_bump( - source_info, - delegate_info, - token_program, + let signer_seeds = Signer::from(seeds); + + pinocchio_token_2022::instructions::Approve { + source: source_info, + delegate: delegate_info, + authority: authority_info, amount, - seeds, - bump, - ) + token_program, + } + .invoke_signed(&[signer_seeds]) } #[inline(always)] -pub fn approve_signed_with_bump<'info>( - source_info: &AccountInfo<'info>, - delegate_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn approve_checked( + source_info: &AccountView, + mint_info: &AccountView, + delegate_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, - seeds: &[&[u8]], - bump: u8, + decimals: u8, ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::approve( - &token_program.key, - source_info.key, - delegate_info.key, - delegate_info.key, - &[delegate_info.key], - amount, - )?, - &[ - token_program.clone(), - source_info.clone(), - delegate_info.clone(), - ], - seeds, - bump, - ) + pinocchio_token_2022::instructions::ApproveChecked { + source: source_info, + mint: mint_info, + delegate: delegate_info, + authority: authority_info, + amount, + decimals, + token_program, + } + .invoke() } #[inline(always)] -pub fn approve_checked<'info>( - source_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - delegate_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn approve_checked_signed( + source_info: &AccountView, + mint_info: &AccountView, + delegate_info: &AccountView, + authority_info: &AccountView, + token_program: &Address, amount: u64, decimals: u8, + seeds: &[Seed; N], ) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::approve_checked( - &token_program.key, - mint_info.key, - source_info.key, - delegate_info.key, - delegate_info.key, - &[delegate_info.key], - amount, - decimals, - )?, - &[ - token_program.clone(), - mint_info.clone(), - source_info.clone(), - delegate_info.clone(), - ], - ) -} + let signer_seeds = Signer::from(seeds); -#[inline(always)] -pub fn approve_checked_signed<'info>( - source_info: &AccountInfo<'info>, - delegate_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - amount: u64, - seeds: &[&[u8]], -) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, &spl_token::ID).1; - approve_signed_with_bump( - source_info, - delegate_info, - token_program, + pinocchio_token_2022::instructions::ApproveChecked { + source: source_info, + mint: mint_info, + delegate: delegate_info, + authority: authority_info, amount, - seeds, - bump, - ) -} - -#[inline(always)] -pub fn approve_checked_signed_with_bump<'info>( - source_info: &AccountInfo<'info>, - mint_info: &AccountInfo<'info>, - delegate_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - decimals: u8, - amount: u64, - seeds: &[&[u8]], - bump: u8, -) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::approve_checked( - &token_program.key, - source_info.key, - mint_info.key, - delegate_info.key, - delegate_info.key, - &[delegate_info.key], - amount, - decimals, - )?, - &[source_info.clone(), delegate_info.clone()], - seeds, - bump, - ) + decimals, + token_program, + } + .invoke_signed(&[signer_seeds]) } /// Initializes a multisignature account with N provided signers. #[inline(always)] -pub fn initialize_multisig<'info>( - multisig_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - n: u8, -) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::initialize_multisig( - &token_program.key, - multisig_info.key, - &[signer_info.key], - n, - )?, - &[token_program.clone(), signer_info.clone()], - ) -} - -#[inline(always)] -pub fn initialize_multisig_signed<'info>( - multisig_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, - m: u8, // number of multi signtures - seeds: &[&[u8]], -) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, &spl_token::ID).1; - initialize_multisig_signed_with_bump(multisig_info, signer_info, token_program, m, seeds, bump) -} - -#[inline(always)] -pub fn initialize_multisig_signed_with_bump<'info>( - multisig_info: &AccountInfo<'info>, - signer_info: &AccountInfo<'info>, - token_program: &AccountInfo<'info>, +pub fn initialize_multisig<'a, const S: usize>( + multisig_info: &AccountView, + rent_sysvar: &AccountView, + signers: &[&'a AccountView; S], + token_program: &Address, m: u8, - seeds: &[&[u8]], - bump: u8, -) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::initialize_multisig( - &token_program.key, - multisig_info.key, - &[signer_info.key], - m, - )?, - &[token_program.clone(), signer_info.clone()], - seeds, - bump, - ) -} - -///Like InitializeAccount2, but does not require the Rent sysvar to be provided -#[inline(always)] -pub fn sync_native(account_info: &AccountInfo) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::sync_native(account_info.owner, account_info.key)?, - &[account_info.clone()], - ) -} - -#[inline(always)] -pub fn sync_native_signed(account_info: &AccountInfo, seeds: &[&[u8]]) -> ProgramResult { - let bump = Pubkey::find_program_address(seeds, &spl_token::ID).1; - sync_native_signed_with_bump(account_info, seeds, bump) -} - -#[inline(always)] -pub fn sync_native_signed_with_bump( - account_info: &AccountInfo, - seeds: &[&[u8]], - bump: u8, ) -> ProgramResult { - invoke_signed_with_bump( - &spl_token_2022::instruction::sync_native(account_info.owner, account_info.key)?, - &[account_info.clone()], - seeds, - bump, - ) + pinocchio_token_2022::instructions::InitializeMultisig { + multisig: multisig_info, + rent_sysvar, + signers, + token_program, + m, + } + .invoke() } +/// Like InitializeAccount2, but does not require the Rent sysvar to be provided #[inline(always)] -pub fn get_account_data_size( - mint_info: &AccountInfo, - extension_types: &[spl_token_2022::extension::ExtensionType], -) -> ProgramResult { - solana_program::program::invoke( - &spl_token_2022::instruction::get_account_data_size( - mint_info.owner, - mint_info.key, - extension_types, - )?, - &[mint_info.clone()], - ) +pub fn sync_native(account_info: &AccountView, token_program: &Address) -> ProgramResult { + pinocchio_token_2022::instructions::SyncNative { + native_token: account_info, + token_program, + } + .invoke() } diff --git a/lib/src/spl/mint.rs b/lib/src/spl/mint.rs index bb5968c..5805ae1 100644 --- a/lib/src/spl/mint.rs +++ b/lib/src/spl/mint.rs @@ -1,43 +1,43 @@ -use solana_program::{program_option::COption, pubkey::Pubkey}; +use pinocchio::Address; pub enum Mint { - V0(spl_token::state::Mint), - V1(spl_token_2022::state::Mint), + V0(pinocchio_token::state::Mint), + V1(pinocchio_token_2022::state::Mint), } impl Mint { - pub fn mint_authority(&self) -> COption { + pub fn mint_authority(&self) -> Option<&Address> { match self { - Mint::V0(mint) => mint.mint_authority, - Mint::V1(mint) => mint.mint_authority, + Mint::V0(mint) => mint.mint_authority(), + Mint::V1(mint) => mint.mint_authority(), } } pub fn supply(&self) -> u64 { match self { - Mint::V0(mint) => mint.supply, - Mint::V1(mint) => mint.supply, + Mint::V0(mint) => mint.supply(), + Mint::V1(mint) => mint.supply(), } } pub fn decimals(&self) -> u8 { match self { - Mint::V0(mint) => mint.decimals, - Mint::V1(mint) => mint.decimals, + Mint::V0(mint) => mint.decimals(), + Mint::V1(mint) => mint.decimals(), } } pub fn is_initialized(&self) -> bool { match self { - Mint::V0(mint) => mint.is_initialized, - Mint::V1(mint) => mint.is_initialized, + Mint::V0(mint) => mint.is_initialized(), + Mint::V1(mint) => mint.is_initialized(), } } - pub fn freeze_authority(&self) -> COption { + pub fn freeze_authority(&self) -> Option<&Address> { match self { - Mint::V0(mint) => mint.freeze_authority, - Mint::V1(mint) => mint.freeze_authority, + Mint::V0(mint) => mint.freeze_authority(), + Mint::V1(mint) => mint.freeze_authority(), } } } diff --git a/lib/src/spl/mod.rs b/lib/src/spl/mod.rs index 2bd0579..e226411 100644 --- a/lib/src/spl/mod.rs +++ b/lib/src/spl/mod.rs @@ -1,9 +1,9 @@ pub mod cpi; pub mod mint; pub mod token; -pub mod validation; +// pub mod validation; pub use cpi::*; pub use mint::*; pub use token::*; -pub use validation::*; +// pub use validation::*; diff --git a/lib/src/spl/token.rs b/lib/src/spl/token.rs index c4ba434..f38f785 100644 --- a/lib/src/spl/token.rs +++ b/lib/src/spl/token.rs @@ -1,36 +1,36 @@ -use solana_program::{program_option::COption, pubkey::Pubkey}; +use pinocchio::Address; pub enum TokenAccount { - V0(spl_token::state::Account), - V1(spl_token_2022::state::Account), + V0(pinocchio_token::state::TokenAccount), + V1(pinocchio_token_2022::state::TokenAccount), } impl TokenAccount { - pub fn mint(&self) -> Pubkey { + pub fn mint(&self) -> &Address { match self { - TokenAccount::V0(account) => account.mint, - TokenAccount::V1(account) => account.mint, + TokenAccount::V0(account) => account.mint(), + TokenAccount::V1(account) => account.mint(), } } - pub fn owner(&self) -> Pubkey { + pub fn owner(&self) -> &Address { match self { - TokenAccount::V0(account) => account.owner, - TokenAccount::V1(account) => account.owner, + TokenAccount::V0(account) => account.owner(), + TokenAccount::V1(account) => account.owner(), } } pub fn amount(&self) -> u64 { match self { - TokenAccount::V0(account) => account.amount, - TokenAccount::V1(account) => account.amount, + TokenAccount::V0(account) => account.amount(), + TokenAccount::V1(account) => account.amount(), } } - pub fn delegate(&self) -> COption { + pub fn delegate(&self) -> Option<&Address> { match self { - TokenAccount::V0(account) => account.delegate, - TokenAccount::V1(account) => account.delegate, + TokenAccount::V0(account) => account.delegate(), + TokenAccount::V1(account) => account.delegate(), } } @@ -41,24 +41,31 @@ impl TokenAccount { } } - pub fn is_native(&self) -> COption { + pub fn is_native(&self) -> bool { match self { - TokenAccount::V0(account) => account.is_native, - TokenAccount::V1(account) => account.is_native, + TokenAccount::V0(account) => account.is_native(), + TokenAccount::V1(account) => account.is_native(), + } + } + + pub fn native_amount(&self) -> Option { + match self { + TokenAccount::V0(account) => account.native_amount(), + TokenAccount::V1(account) => account.native_amount(), } } pub fn delegated_amount(&self) -> u64 { match self { - TokenAccount::V0(account) => account.delegated_amount, - TokenAccount::V1(account) => account.delegated_amount, + TokenAccount::V0(account) => account.delegated_amount(), + TokenAccount::V1(account) => account.delegated_amount(), } } - pub fn close_authority(&self) -> COption { + pub fn close_authority(&self) -> Option<&Address> { match self { - TokenAccount::V0(account) => account.close_authority, - TokenAccount::V1(account) => account.close_authority, + TokenAccount::V0(account) => account.close_authority(), + TokenAccount::V1(account) => account.close_authority(), } } } diff --git a/lib/src/utils.rs b/lib/src/utils.rs index 98e3016..2d866cb 100644 --- a/lib/src/utils.rs +++ b/lib/src/utils.rs @@ -1,9 +1,10 @@ -use solana_program::{program_error::ProgramError, pubkey::Pubkey}; +use solana_address::Address; +use solana_program_error::ProgramError; /// Parses an instruction from the instruction data. pub fn parse_instruction<'a, T: std::convert::TryFrom>( - api_id: &'a Pubkey, - program_id: &'a Pubkey, + api_id: &Address, + program_id: &Address, data: &'a [u8], ) -> Result<(T, &'a [u8]), ProgramError> { // Validate the program id is valid.