Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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