Skip to content

Steel token2022 examples #394

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
2 changes: 2 additions & 0 deletions tokens/token-2022/cpi-guard/steel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
test-ledger
22 changes: 22 additions & 0 deletions tokens/token-2022/cpi-guard/steel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[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]
steel-api = { path = "./api", version = "0.1.0" }
bytemuck = "1.14"
num_enum = "0.7"
solana-program = "2.1"
steel = "3.0"
thiserror = "1.0"
spl-token-2022 = {version = "7.0.0", features = ["no-entrypoint"]}
28 changes: 28 additions & 0 deletions tokens/token-2022/cpi-guard/steel/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Steel

**Steel** 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
```
19 changes: 19 additions & 0 deletions tokens/token-2022/cpi-guard/steel/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[package]
name = "steel-api"
description = "API for interacting with the Steel 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
spl-token-2022.workspace = true
10 changes: 10 additions & 0 deletions tokens/token-2022/cpi-guard/steel/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 SteelError {
#[error("This is a dummy error")]
Dummy = 0,
}

error!(SteelError);
13 changes: 13 additions & 0 deletions tokens/token-2022/cpi-guard/steel/api/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use steel::*;

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

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

instruction!(SteelInstruction, CpiBurn);
14 changes: 14 additions & 0 deletions tokens/token-2022/cpi-guard/steel/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub mod error;
pub mod instruction;
pub mod sdk;

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

use steel::*;

// TODO Set program id
declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35");
17 changes: 17 additions & 0 deletions tokens/token-2022/cpi-guard/steel/api/src/sdk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use steel::*;

use crate::prelude::*;

pub fn cpi_burn(signer: Pubkey, mint: Pubkey, recipient_token_account: Pubkey) -> Instruction {
Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(signer, true),
AccountMeta::new(mint, false),
AccountMeta::new(recipient_token_account, false),
AccountMeta::new_readonly(system_program::ID, false),
AccountMeta::new_readonly(spl_token_2022::ID, false),
],
data: CpiBurn {}.to_bytes(),
}
}
27 changes: 27 additions & 0 deletions tokens/token-2022/cpi-guard/steel/program/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "steel-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]
steel-api.workspace = true
solana-program.workspace = true
steel.workspace = true
spl-token-2022.workspace = true

[dev-dependencies]
base64 = "0.21"
rand = "0.8.5"
solana-program-test = "2.1"
solana-sdk = "2.1"
tokio = { version = "1.35", features = ["full"] }
54 changes: 54 additions & 0 deletions tokens/token-2022/cpi-guard/steel/program/src/cpi_burn.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use solana_program::{msg, program::invoke};
use spl_token_2022::instruction::{burn, mint_to};
use steel::*;

pub fn process_cpi_burn(accounts: &[AccountInfo<'_>], _data: &[u8]) -> ProgramResult {
// Load accounts.
let [signer_info, mint_info, recipient_token_account_info, system_program, token_program] =
accounts
else {
return Err(ProgramError::NotEnoughAccountKeys);
};

//Validation
signer_info.is_signer()?;
recipient_token_account_info.is_writable()?;
token_program.is_program(&spl_token_2022::ID)?;
system_program.is_program(&system_program::ID)?;

invoke(
&mint_to(
token_program.key,
mint_info.key,
recipient_token_account_info.key,
signer_info.key,
&[],
1000,
)?,
&[
mint_info.clone(),
recipient_token_account_info.clone(),
signer_info.clone(),
],
)?;

invoke(
&burn(
token_program.key,
recipient_token_account_info.key,
mint_info.key,
signer_info.key,
&[],
100,
)?,
&[
recipient_token_account_info.clone(),
mint_info.clone(),
signer_info.clone(),
],
)?;

msg!("Cpi Guard Extension Test: Burn.");

Ok(())
}
22 changes: 22 additions & 0 deletions tokens/token-2022/cpi-guard/steel/program/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
mod cpi_burn;

use cpi_burn::*;

use steel::*;
use steel_api::prelude::*;

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

match ix {
SteelInstruction::CpiBurn => process_cpi_burn(accounts, data)?,
}

Ok(())
}

entrypoint!(process_instruction);
133 changes: 133 additions & 0 deletions tokens/token-2022/cpi-guard/steel/program/tests/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
use solana_program::{hash::Hash, program_pack::Pack};
use solana_program_test::{processor, BanksClient, ProgramTest};
use solana_sdk::{
signature::Keypair, signer::Signer, system_instruction::create_account,
transaction::Transaction,
};
use spl_token_2022::{
extension::{
cpi_guard::instruction::{disable_cpi_guard, enable_cpi_guard},
ExtensionType,
},
instruction::{initialize_account3, initialize_mint2},
state::{Account, Mint},
};
use steel_api::prelude::*;

async fn setup() -> (BanksClient, Keypair, Hash) {
let mut program_test = ProgramTest::new(
"steel_program",
steel_api::ID,
processor!(steel_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 mint = Keypair::new();
let token_acc = Keypair::new();

//Setup Mint.
let create_mint_ix = create_account(
&payer.pubkey(),
&mint.pubkey(),
banks.get_rent().await.unwrap().minimum_balance(Mint::LEN),
Mint::LEN as u64,
&spl_token_2022::ID,
);
let init_mint_ix = initialize_mint2(
&spl_token_2022::ID,
&mint.pubkey(),
&payer.pubkey(),
None,
6,
)
.unwrap();

//Setup Token Account
let space =
ExtensionType::try_calculate_account_len::<Account>(&[ExtensionType::CpiGuard]).unwrap();

let create_acc_ix = create_account(
&payer.pubkey(),
&token_acc.pubkey(),
banks.get_rent().await.unwrap().minimum_balance(space),
space as u64,
&spl_token_2022::ID,
);

let init_acc_ix = initialize_account3(
&spl_token_2022::ID,
&token_acc.pubkey(),
&mint.pubkey(),
&payer.pubkey(),
)
.unwrap();

//Initialize Cpi Guard Extension
let enable_cpi_guard_ix = enable_cpi_guard(
&spl_token_2022::ID,
&token_acc.pubkey(),
&payer.pubkey(),
&[],
)
.unwrap();

let tx = Transaction::new_signed_with_payer(
&[
create_mint_ix,
init_mint_ix,
create_acc_ix,
init_acc_ix,
enable_cpi_guard_ix,
],
Some(&payer.pubkey()),
&[&payer, &mint, &token_acc],
blockhash,
);
let res = banks.process_transaction(tx).await;
assert!(res.is_ok());

//Try to burn tokens via cpi, should fail
let cpi_burn_ix = cpi_burn(payer.pubkey(), mint.pubkey(), token_acc.pubkey());

let tx = Transaction::new_signed_with_payer(
&[cpi_burn_ix],
Some(&payer.pubkey()),
&[&payer],
blockhash,
);
let res = banks.process_transaction(tx).await;

let err_string = format!("{:?}", res);

assert!(
err_string.contains("Custom(43)"),
"Expected TokenError::CpiGuardBurnBlocked(43) , got: {}",
err_string
);

//Disable CPI Guard and try burn again, should pass
let disable_cpi_ix = disable_cpi_guard(
&spl_token_2022::ID,
&token_acc.pubkey(),
&payer.pubkey(),
&[],
)
.unwrap();
let cpi_burn_ix = cpi_burn(payer.pubkey(), mint.pubkey(), token_acc.pubkey());

let tx = Transaction::new_signed_with_payer(
&[disable_cpi_ix, cpi_burn_ix],
Some(&payer.pubkey()),
&[&payer],
blockhash,
);
let res = banks.process_transaction(tx).await;
assert!(res.is_ok());
}
2 changes: 2 additions & 0 deletions tokens/token-2022/default-account-state/steel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
test-ledger
23 changes: 23 additions & 0 deletions tokens/token-2022/default-account-state/steel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[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]
steel-api = { path = "./api", version = "0.1.0" }
bytemuck = "1.14"
num_enum = "0.7"
solana-program = "2.1"
steel = "4.0"
thiserror = "1.0"
spl-token-2022 = {version = "7.0.0", features = ["no-entrypoint"]}

Loading
Loading