Skip to content

Commit

Permalink
add basics/cross-program-invocation/steel (#248)
Browse files Browse the repository at this point in the history
  • Loading branch information
Perelyn-sama authored Jan 2, 2025
1 parent a667981 commit ecf7486
Show file tree
Hide file tree
Showing 29 changed files with 591 additions and 0 deletions.
6 changes: 6 additions & 0 deletions basics/cross-program-invocation/steel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
## Cross Program Invocation steel example

### Programs

- [Hand](./hand/README.md)
- [Lever](./lever/README.md)
2 changes: 2 additions & 0 deletions basics/cross-program-invocation/steel/hand/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
test-ledger
25 changes: 25 additions & 0 deletions basics/cross-program-invocation/steel/hand/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[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]
hand-api = { path = "./api", version = "0.1.0" }
lever-api = { path = "../lever/api", version = "0.1.0" }
lever-program = { path = "../lever/program", version = "0.1.0", features = [
"cpi",
] }
bytemuck = "1.14"
num_enum = "0.7"
solana-program = "1.18"
steel = "2.0"
thiserror = "1.0"
21 changes: 21 additions & 0 deletions basics/cross-program-invocation/steel/hand/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Hand

**Hand** is a ...

## API
- [`Instruction`](api/src/instruction.rs) – Declared instructions.

## Instructions
- [`PullLever`](program/src/pull_lever.rs) – Pull Lever ...

## Get started

Compile your program:
```sh
steel build
```

Run unit and integration tests:
```sh
steel test
```
19 changes: 19 additions & 0 deletions basics/cross-program-invocation/steel/hand/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "hand-api"
description = "API for interacting with the Hand 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
lever-api.workspace = true
15 changes: 15 additions & 0 deletions basics/cross-program-invocation/steel/hand/api/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use steel::*;

#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
pub enum HandInstruction {
PullLever = 0,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct PullLever {
pub name: [u8; 32],
}

instruction!(HandInstruction, PullLever);
12 changes: 12 additions & 0 deletions basics/cross-program-invocation/steel/hand/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
pub mod instruction;
pub mod sdk;

pub mod prelude {
pub use crate::instruction::*;
pub use crate::sdk::*;
}

use steel::*;

// TODO Set program id
declare_id!("Bi5N7SUQhpGknVcqPTzdFFVueQoxoUu8YTLz75J6fT8A");
20 changes: 20 additions & 0 deletions basics/cross-program-invocation/steel/hand/api/src/sdk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use lever_api::prelude::*;
use steel::*;

use crate::prelude::*;

pub fn pull_lever(power_account: Pubkey, name: &str) -> Instruction {
// pub fn pull_lever(power_account: Pubkey, lever_program: Pubkey, name: &str) -> Instruction {
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(power_account, false),
// AccountMeta::new(lever_program, false),
AccountMeta::new_readonly(lever_api::ID, false),
],
data: PullLever {
name: str_to_bytes(name),
}
.to_bytes(),
}
}
28 changes: 28 additions & 0 deletions basics/cross-program-invocation/steel/hand/program/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "hand-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]
hand-api.workspace = true
lever-api.workspace = true
lever-program.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"] }
22 changes: 22 additions & 0 deletions basics/cross-program-invocation/steel/hand/program/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
mod pull_lever;

use pull_lever::*;

use hand_api::prelude::*;
use steel::*;

pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
data: &[u8],
) -> ProgramResult {
let (ix, data) = parse_instruction(&hand_api::ID, program_id, data)?;

match ix {
HandInstruction::PullLever => process_pull_lever(accounts, data)?,
}

Ok(())
}

entrypoint!(process_instruction);
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use hand_api::prelude::*;
use lever_api::prelude::*;
use steel::*;

pub fn process_pull_lever(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
// Parse args.
let args = PullLever::try_from_bytes(data)?;
let name = bytes_to_str(&args.name);

// Load accounts.
let [power_info, lever_program] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};

power_info.is_writable()?;

let ix = switch_power(*power_info.key, &name);

solana_program::program::invoke(&ix, &[power_info.clone(), lever_program.clone()])?;

Ok(())
}
51 changes: 51 additions & 0 deletions basics/cross-program-invocation/steel/hand/program/tests/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use hand_api::prelude::*;
use lever_api::prelude::*;
use solana_program::hash::Hash;
use solana_program_test::{processor, BanksClient, ProgramTest};
use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction};

async fn setup() -> (BanksClient, Keypair, Hash) {
let mut program_test = ProgramTest::new(
"hand_program",
hand_api::ID,
processor!(hand_program::process_instruction),
);

program_test.add_program(
"lever_program",
lever_api::ID,
processor!(lever_program::process_instruction),
);

program_test.prefer_bpf(true);
program_test.start().await
}

#[tokio::test]
async fn run_test() {
// Setup test
let (mut banks, payer, blockhash) = setup().await;
let power_account = Keypair::new();

// Submit initialize transaction.
let ix = initialize(payer.pubkey(), power_account.pubkey());
let tx = Transaction::new_signed_with_payer(
&[ix],
Some(&payer.pubkey()),
&[&payer, &power_account],
blockhash,
);
let res = banks.process_transaction(tx).await;
assert!(res.is_ok());

// Submit pull_lever transaction.
let ix = pull_lever(power_account.pubkey(), "Chris");
let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash);
let res = banks.process_transaction(tx).await;
assert!(res.is_ok());

let ix = pull_lever(power_account.pubkey(), "Ashley");
let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash);
let res = banks.process_transaction(tx).await;
assert!(res.is_ok());
}
2 changes: 2 additions & 0 deletions basics/cross-program-invocation/steel/lever/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
test-ledger
21 changes: 21 additions & 0 deletions basics/cross-program-invocation/steel/lever/Cargo.toml
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]
lever-api = { path = "./api", version = "0.1.0" }
bytemuck = "1.14"
num_enum = "0.7"
solana-program = "1.18"
steel = "2.0"
thiserror = "1.0"
28 changes: 28 additions & 0 deletions basics/cross-program-invocation/steel/lever/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Lever

**Lever** 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
- [`SwitchPower`](program/src/switch_power.rs) – Switch Power ...
- [`Initialize`](program/src/initialize.rs) – Initialize ...

## State
- [`PowerStatus`](api/src/state/power_status.rs) – Power status ...

## Get started

Compile your program:
```sh
steel build
```

Run unit and integration tests:
```sh
steel test
```
18 changes: 18 additions & 0 deletions basics/cross-program-invocation/steel/lever/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "lever-api"
description = "API for interacting with the Lever 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
2 changes: 2 additions & 0 deletions basics/cross-program-invocation/steel/lever/api/src/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// Seed of the counter account PDA.
pub const COUNTER: &[u8] = b"counter";
10 changes: 10 additions & 0 deletions basics/cross-program-invocation/steel/lever/api/src/error.rs
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 LeverError {
#[error("This is a dummy error")]
Dummy = 0,
}

error!(LeverError);
21 changes: 21 additions & 0 deletions basics/cross-program-invocation/steel/lever/api/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use steel::*;

#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
pub enum LeverInstruction {
Initialize = 0,
SetPowerStatus = 1,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Initialize {}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct SetPowerStatus {
pub name: [u8; 32],
}

instruction!(LeverInstruction, Initialize);
instruction!(LeverInstruction, SetPowerStatus);
20 changes: 20 additions & 0 deletions basics/cross-program-invocation/steel/lever/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
pub mod consts;
pub mod error;
pub mod instruction;
pub mod sdk;
pub mod state;
pub mod utils;

pub mod prelude {
pub use crate::consts::*;
pub use crate::error::*;
pub use crate::instruction::*;
pub use crate::sdk::*;
pub use crate::state::*;
pub use crate::utils::*;
}

use steel::*;

// TODO Set program id
declare_id!("E64FVeubGC4NPNF2UBJYX4AkrVowf74fRJD9q6YhwstN");
Loading

0 comments on commit ecf7486

Please sign in to comment.