-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
dd771c7
commit 85082a3
Showing
15 changed files
with
359 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
target | ||
test-ledger |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
[workspace] | ||
resolver = "2" | ||
members = ["api", "program"] | ||
|
||
[workspace.package] | ||
version = "0.1.0" | ||
edition = "2021" | ||
license = "Apache-2.0" | ||
homepage = "" | ||
documentation = "" | ||
repository = "" | ||
readme = "./README.md" | ||
keywords = ["solana"] | ||
|
||
[workspace.dependencies] | ||
rent_example-api = { path = "./api", version = "0.1.0" } | ||
bytemuck = "1.14" | ||
num_enum = "0.7" | ||
solana-program = "1.18" | ||
steel = "2.0" | ||
thiserror = "1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# RentExample | ||
|
||
**RentExample** 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 | ||
- [`Add`](program/src/add.rs) – Add ... | ||
- [`Initialize`](program/src/initialize.rs) – Initialize ... | ||
|
||
## State | ||
- [`Counter`](api/src/state/counter.rs) – Counter ... | ||
|
||
## Get started | ||
|
||
Compile your program: | ||
```sh | ||
steel build | ||
``` | ||
|
||
Run unit and integration tests: | ||
```sh | ||
steel test | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[package] | ||
name = "rent_example-api" | ||
description = "API for interacting with the RentExample program" | ||
version.workspace = true | ||
edition.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
documentation.workspace = true | ||
repository.workspace = true | ||
readme.workspace = true | ||
keywords.workspace = true | ||
|
||
[dependencies] | ||
bytemuck.workspace = true | ||
num_enum.workspace = true | ||
solana-program.workspace = true | ||
steel.workspace = true | ||
thiserror.workspace = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
use steel::*; | ||
|
||
#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)] | ||
#[repr(u32)] | ||
pub enum RentExampleError { | ||
#[error("This is a dummy error")] | ||
Dummy = 0, | ||
} | ||
|
||
error!(RentExampleError); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use steel::*; | ||
|
||
#[repr(u8)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)] | ||
pub enum RentInstruction { | ||
CreateSystemAccount = 0, | ||
} | ||
|
||
#[repr(C)] | ||
#[derive(Clone, Copy, Debug, Pod, Zeroable)] | ||
pub struct CreateSystemAccount { | ||
pub name: [u8; 32], | ||
pub address: [u8; 64], | ||
} | ||
|
||
instruction!(RentInstruction, CreateSystemAccount); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
pub mod error; | ||
pub mod instruction; | ||
pub mod sdk; | ||
pub mod state; | ||
|
||
pub mod prelude { | ||
pub use crate::error::*; | ||
pub use crate::instruction::*; | ||
pub use crate::sdk::*; | ||
pub use crate::state::*; | ||
// Re-export common solana dependencies | ||
pub use solana_program::{ | ||
account_info::AccountInfo, entrypoint::ProgramResult, msg, pubkey::Pubkey, rent::Rent, | ||
system_program, | ||
}; | ||
} | ||
|
||
use steel::*; | ||
|
||
// TODO Set program id | ||
declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use crate::prelude::*; | ||
use steel::*; | ||
|
||
pub fn create_system_account( | ||
payer: Pubkey, | ||
new_account: Pubkey, | ||
name: String, | ||
address: String, | ||
) -> Instruction { | ||
let mut name_bytes = [0u8; 32]; | ||
let mut address_bytes = [0u8; 64]; | ||
|
||
name_bytes[..name.len()].copy_from_slice(name.as_bytes()); | ||
address_bytes[..address.len()].copy_from_slice(address.as_bytes()); | ||
|
||
Instruction { | ||
program_id: crate::ID, | ||
accounts: vec![ | ||
AccountMeta::new(payer, true), | ||
AccountMeta::new(new_account, true), | ||
AccountMeta::new_readonly(system_program::ID, false), | ||
], | ||
data: CreateSystemAccount { | ||
name: name_bytes, | ||
address: address_bytes, | ||
} | ||
.to_bytes(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use super::RentAccount; | ||
use steel::*; | ||
|
||
#[repr(C)] | ||
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] | ||
pub struct Address { | ||
pub name: [u8; 32], | ||
pub address: [u8; 64], | ||
} | ||
|
||
account!(RentAccount, Address); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
mod address; | ||
|
||
pub use address::*; | ||
|
||
use steel::*; | ||
|
||
#[repr(u8)] | ||
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)] | ||
pub enum RentAccount { | ||
Address = 0, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"name": "rent-example", | ||
"version": "1.0.0", | ||
"description": "rent example with steel framework for solana", | ||
"scripts": { | ||
"test": "cargo test-sbf", | ||
"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/rent_example_program.so" | ||
}, | ||
"keywords": [], | ||
"author": "Sabir Khan", | ||
"license": "ISC" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[package] | ||
name = "rent_example-program" | ||
description = "" | ||
version.workspace = true | ||
edition.workspace = true | ||
license.workspace = true | ||
homepage.workspace = true | ||
documentation.workspace = true | ||
repository.workspace = true | ||
readme.workspace = true | ||
keywords.workspace = true | ||
|
||
[lib] | ||
crate-type = ["cdylib", "lib"] | ||
|
||
[dependencies] | ||
rent_example-api.workspace = true | ||
solana-program.workspace = true | ||
steel.workspace = true | ||
|
||
[dev-dependencies] | ||
base64 = "0.21" | ||
rand = "0.8.5" | ||
solana-program-test = "1.18" | ||
solana-sdk = "1.18" | ||
tokio = { version = "1.35", features = ["full"] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use rent_example_api::prelude::*; | ||
use solana_program::msg; | ||
use steel::*; | ||
|
||
pub fn process_create_account(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult { | ||
let args = CreateSystemAccount::try_from_bytes(data)?; | ||
|
||
let [payer_info, new_account_info, system_program] = accounts else { | ||
return Err(ProgramError::NotEnoughAccountKeys); | ||
}; | ||
|
||
payer_info.is_signer()?; | ||
new_account_info.is_signer()?; | ||
|
||
let account_size = std::mem::size_of::<Address>(); | ||
let rent = Rent::get()?; | ||
let lamports_required = rent.minimum_balance(account_size); | ||
|
||
msg!("Account size: {}", account_size); | ||
msg!("Lamports required: {}", lamports_required); | ||
|
||
// Create account with correct type argument | ||
create_account::<Address>( | ||
new_account_info, | ||
system_program, | ||
payer_info, | ||
&rent_example_api::ID, | ||
&[], | ||
)?; | ||
|
||
let address = new_account_info.as_account_mut::<Address>(&rent_example_api::ID)?; | ||
address.name = args.name; | ||
address.address = args.address; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
mod create_account; | ||
|
||
use create_account::*; | ||
use rent_example_api::prelude::*; | ||
use steel::*; | ||
|
||
pub fn process_instruction( | ||
program_id: &Pubkey, | ||
accounts: &[AccountInfo], | ||
data: &[u8], | ||
) -> ProgramResult { | ||
let (ix, data) = parse_instruction::<RentInstruction>(&rent_example_api::ID, program_id, data)?; | ||
|
||
match ix { | ||
RentInstruction::CreateSystemAccount => process_create_account(accounts, data)?, | ||
} | ||
|
||
Ok(()) | ||
} | ||
|
||
entrypoint!(process_instruction); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
use rent_example_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( | ||
"rent_example_program", | ||
rent_example_api::ID, | ||
processor!(rent_example_program::process_instruction), | ||
); | ||
program_test.prefer_bpf(true); | ||
program_test.start().await | ||
} | ||
|
||
#[tokio::test] | ||
async fn test_create_system_account() { | ||
// Setup test environment | ||
let (mut banks_client, payer, recent_blockhash) = setup().await; | ||
|
||
// Generate a new keypair for the account we'll create | ||
let new_account = Keypair::new(); | ||
|
||
// Test data | ||
let name = "John Doe"; | ||
let address = "123 Blockchain Street"; | ||
|
||
// Create the instruction | ||
let ix = create_system_account( | ||
payer.pubkey(), | ||
new_account.pubkey(), | ||
name.to_string(), | ||
address.to_string(), | ||
); | ||
|
||
// Create and send transaction | ||
let mut transaction = Transaction::new_signed_with_payer( | ||
&[ix], | ||
Some(&payer.pubkey()), | ||
&[&payer, &new_account], | ||
recent_blockhash, | ||
); | ||
|
||
// Process transaction | ||
let result = banks_client.process_transaction(transaction).await; | ||
assert!( | ||
result.is_ok(), | ||
"Failed to process transaction: {:?}", | ||
result | ||
); | ||
|
||
// Fetch and verify the created account | ||
let account = banks_client | ||
.get_account(new_account.pubkey()) | ||
.await | ||
.expect("Failed to get account") | ||
.expect("Account not found"); | ||
|
||
// Verify account owner | ||
assert_eq!( | ||
account.owner, | ||
rent_example_api::ID, | ||
"Incorrect account owner" | ||
); | ||
|
||
// Deserialize and verify account data | ||
let address_account = | ||
Address::try_from_bytes(&account.data).expect("Failed to deserialize account data"); | ||
|
||
// Convert stored bytes back to strings for comparison | ||
let stored_name = String::from_utf8( | ||
address_account | ||
.name | ||
.iter() | ||
.take_while(|&&b| b != 0) | ||
.cloned() | ||
.collect::<Vec<u8>>(), | ||
) | ||
.unwrap(); | ||
|
||
let stored_address = String::from_utf8( | ||
address_account | ||
.address | ||
.iter() | ||
.take_while(|&&b| b != 0) | ||
.cloned() | ||
.collect::<Vec<u8>>(), | ||
) | ||
.unwrap(); | ||
|
||
// Verify the stored data matches what we sent | ||
assert_eq!(stored_name, name, "Stored name doesn't match"); | ||
assert_eq!(stored_address, address, "Stored address doesn't match"); | ||
} |