Skip to content

Commit aa13568

Browse files
feat: add Quasar variants for checking-accounts, create-account, program-derived-addresses, pda-rent-payer
1 parent c87324a commit aa13568

32 files changed

Lines changed: 924 additions & 0 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Build artifacts
2+
/target
3+
4+
# Dependencies
5+
node_modules
6+
7+
# Environment
8+
.env
9+
.env.*
10+
11+
# OS
12+
.DS_Store
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "quasar-checking-accounts"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# Standalone workspace — not part of the root program-examples workspace.
7+
# Quasar uses a different resolver and dependency tree.
8+
[workspace]
9+
10+
[lints.rust.unexpected_cfgs]
11+
level = "warn"
12+
check-cfg = [
13+
'cfg(target_os, values("solana"))',
14+
]
15+
16+
[lib]
17+
crate-type = ["cdylib"]
18+
19+
[features]
20+
alloc = []
21+
client = []
22+
debug = []
23+
24+
[dependencies]
25+
quasar-lang = "0.0"
26+
solana-instruction = { version = "3.2.0" }
27+
28+
[dev-dependencies]
29+
quasar-checking-accounts-client = { path = "target/client/rust/quasar-checking-accounts-client" }
30+
quasar-svm = { version = "0.1" }
31+
solana-account = { version = "3.4.0" }
32+
solana-address = { version = "2.2.0", features = ["decode"] }
33+
solana-instruction = { version = "3.2.0", features = ["bincode"] }
34+
solana-pubkey = { version = "4.1.0" }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[project]
2+
name = "quasar_checking_accounts"
3+
4+
[toolchain]
5+
type = "solana"
6+
7+
[testing]
8+
language = "rust"
9+
10+
[testing.rust]
11+
framework = "quasar-svm"
12+
13+
[testing.rust.test]
14+
program = "cargo"
15+
args = [
16+
"test",
17+
"tests::",
18+
]
19+
20+
[clients]
21+
languages = ["rust"]
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use quasar_lang::prelude::*;
2+
3+
/// Demonstrates Quasar's account type constraints:
4+
/// - `Signer`: automatically verified as a transaction signer
5+
/// - `UncheckedAccount`: no runtime checks (opt-in unchecked access)
6+
/// - `Program<System>`: verified as the system program (executable + address check)
7+
///
8+
/// Note: Anchor's `#[account(owner = id())]` owner constraint is not directly available
9+
/// in Quasar. Owner checks can be done manually in the instruction body if needed.
10+
#[derive(Accounts)]
11+
pub struct CheckAccounts<'info> {
12+
/// Checks that this account signed the transaction.
13+
pub payer: &'info Signer,
14+
/// No checks performed — the caller is responsible for validation.
15+
#[account(mut)]
16+
pub account_to_create: &'info mut UncheckedAccount,
17+
/// No automatic owner check in Quasar; see note above.
18+
#[account(mut)]
19+
pub account_to_change: &'info mut UncheckedAccount,
20+
/// Checks the account is executable and matches the system program address.
21+
pub system_program: &'info Program<System>,
22+
}
23+
24+
impl<'info> CheckAccounts<'info> {
25+
#[inline(always)]
26+
pub fn check_accounts(&self) -> Result<(), ProgramError> {
27+
// All validation happens declaratively via the account types above.
28+
// If any check fails, the runtime rejects the transaction before this runs.
29+
Ok(())
30+
}
31+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
pub mod check_accounts;
2+
3+
pub use check_accounts::*;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#![cfg_attr(not(test), no_std)]
2+
3+
use quasar_lang::prelude::*;
4+
5+
mod instructions;
6+
use instructions::*;
7+
#[cfg(test)]
8+
mod tests;
9+
10+
declare_id!("ECWPhR3rJbaPfyNFgphnjxSEexbTArc7vxD8fnW6tgKw");
11+
12+
#[program]
13+
mod quasar_checking_accounts {
14+
use super::*;
15+
16+
/// Account validation in Quasar is done using the types in #[derive(Accounts)] structs:
17+
/// - Signer: checks the account has signed the transaction
18+
/// - UncheckedAccount: no validation (opt-in to unchecked access)
19+
/// - Program<System>: checks account is executable and is the system program
20+
#[instruction(discriminator = 0)]
21+
pub fn check_accounts(ctx: Ctx<CheckAccounts>) -> Result<(), ProgramError> {
22+
ctx.accounts.check_accounts()
23+
}
24+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use quasar_svm::{Account, Instruction, Pubkey, QuasarSvm};
2+
use solana_address::Address;
3+
4+
use quasar_checking_accounts_client::CheckAccountsInstruction;
5+
6+
fn setup() -> QuasarSvm {
7+
let elf = include_bytes!("../target/deploy/quasar_checking_accounts.so");
8+
QuasarSvm::new().with_program(&Pubkey::from(crate::ID), elf)
9+
}
10+
11+
fn signer(address: Pubkey) -> Account {
12+
quasar_svm::token::create_keyed_system_account(&address, 10_000_000_000)
13+
}
14+
15+
fn system_account(address: Pubkey, lamports: u64) -> Account {
16+
Account {
17+
address,
18+
lamports,
19+
data: vec![],
20+
owner: quasar_svm::system_program::ID,
21+
executable: false,
22+
}
23+
}
24+
25+
fn program_owned_account(address: Pubkey, lamports: u64) -> Account {
26+
Account {
27+
address,
28+
lamports,
29+
data: vec![0u8; 32],
30+
owner: Pubkey::from(crate::ID),
31+
executable: false,
32+
}
33+
}
34+
35+
#[test]
36+
fn test_check_accounts_succeeds() {
37+
let mut svm = setup();
38+
39+
let payer = Pubkey::new_unique();
40+
let account_to_create = Pubkey::new_unique();
41+
let account_to_change = Pubkey::new_unique();
42+
let system_program = quasar_svm::system_program::ID;
43+
44+
let instruction: Instruction = CheckAccountsInstruction {
45+
payer: Address::from(payer.to_bytes()),
46+
account_to_create: Address::from(account_to_create.to_bytes()),
47+
account_to_change: Address::from(account_to_change.to_bytes()),
48+
system_program: Address::from(system_program.to_bytes()),
49+
}
50+
.into();
51+
52+
let result = svm.process_instruction(
53+
&instruction,
54+
&[
55+
signer(payer),
56+
system_account(account_to_create, 0),
57+
program_owned_account(account_to_change, 1_000_000),
58+
],
59+
);
60+
61+
result.assert_success();
62+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Build artifacts
2+
/target
3+
4+
# Dependencies
5+
node_modules
6+
7+
# Environment
8+
.env
9+
.env.*
10+
11+
# OS
12+
.DS_Store
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "quasar-create-account"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# Standalone workspace — not part of the root program-examples workspace.
7+
# Quasar uses a different resolver and dependency tree.
8+
[workspace]
9+
10+
[lints.rust.unexpected_cfgs]
11+
level = "warn"
12+
check-cfg = [
13+
'cfg(target_os, values("solana"))',
14+
]
15+
16+
[lib]
17+
crate-type = ["cdylib"]
18+
19+
[features]
20+
alloc = []
21+
client = []
22+
debug = []
23+
24+
[dependencies]
25+
quasar-lang = "0.0"
26+
solana-instruction = { version = "3.2.0" }
27+
28+
[dev-dependencies]
29+
quasar-create-account-client = { path = "target/client/rust/quasar-create-account-client" }
30+
quasar-svm = { version = "0.1" }
31+
solana-account = { version = "3.4.0" }
32+
solana-address = { version = "2.2.0", features = ["decode"] }
33+
solana-instruction = { version = "3.2.0", features = ["bincode"] }
34+
solana-pubkey = { version = "4.1.0" }
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[project]
2+
name = "quasar_create_account"
3+
4+
[toolchain]
5+
type = "solana"
6+
7+
[testing]
8+
language = "rust"
9+
10+
[testing.rust]
11+
framework = "quasar-svm"
12+
13+
[testing.rust.test]
14+
program = "cargo"
15+
args = [
16+
"test",
17+
"tests::",
18+
]
19+
20+
[clients]
21+
languages = ["rust"]

0 commit comments

Comments
 (0)