Jelajahi Sumber

add tokens/create-token/steel (#299)

Eric Alaribe 9 bulan lalu
induk
melakukan
cb4b9696ee

+ 2 - 0
tokens/create-token/steel/.gitignore

@@ -0,0 +1,2 @@
+target
+test-ledger

+ 21 - 0
tokens/create-token/steel/Cargo.toml

@@ -0,0 +1,21 @@
+[workspace]
+resolver = "2"
+members = ["api", "program"]
+
+[workspace.package]
+version = "0.1.0"
+edition = "2021"
+license = "Apache-2.0"
+homepage = ""
+documentation = ""
+respository = ""
+readme = "./README.md"
+keywords = ["solana"]
+
+[workspace.dependencies]
+steel-api = { path = "./api", version = "0.1.0" }
+bytemuck = "1.14"
+num_enum = "0.7"
+solana-program = "1.18"
+steel = "1.3"
+thiserror = "1.0"

+ 22 - 0
tokens/create-token/steel/README.md

@@ -0,0 +1,22 @@
+# 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
+- [`Hello`](program/src/hello.rs) – Hello ...
+
+## State
+- [`User`](api/src/state/user.rs) – User ...
+
+## Tests
+
+To run the test suit, use the Solana toolchain:
+```
+cargo test-sbf         
+```

+ 13 - 0
tokens/create-token/steel/api/Cargo.toml

@@ -0,0 +1,13 @@
+[package]
+name = "steel-api"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+bytemuck.workspace = true
+num_enum.workspace = true
+solana-program.workspace = true
+spl-token = "6.0.0"
+steel.workspace = true
+steel-program = { version = "0.1.0", path = "../program" }
+thiserror.workspace = true

+ 8 - 0
tokens/create-token/steel/api/src/consts.rs

@@ -0,0 +1,8 @@
+/// Seed of the counter account PDA.
+pub const MINT: &[u8] = b"mint";
+
+pub const MINT_NOISE: [u8; 16] = [
+    89, 157, 88, 232, 243, 249, 197, 132, 199, 49, 19, 234, 91, 94, 150, 41,
+];
+
+pub const METADATA: &[u8] = b"metadata";

+ 10 - 0
tokens/create-token/steel/api/src/error.rs

@@ -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);

+ 17 - 0
tokens/create-token/steel/api/src/instruction.rs

@@ -0,0 +1,17 @@
+use steel::*;
+
+#[repr(u8)]
+#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
+pub enum SteelInstruction {
+    Create_Token = 0,
+}
+
+#[repr(C)]
+#[derive(Clone, Copy, Debug, Pod, Zeroable)]
+pub struct Create_Token {
+    pub token_name: [u8; 32],
+    pub token_symbol: [u8; 8],
+    pub token_uri: [u8; 64],
+}
+
+instruction!(SteelInstruction, Create_Token);

+ 16 - 0
tokens/create-token/steel/api/src/lib.rs

@@ -0,0 +1,16 @@
+pub mod consts;
+pub mod error;
+pub mod instruction;
+pub mod sdk;
+
+pub mod prelude {
+    pub use crate::consts::*;
+    pub use crate::error::*;
+    pub use crate::instruction::*;
+    pub use crate::sdk::*;
+}
+
+use steel::*;
+
+// TODO Set program id
+declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35");

+ 27 - 0
tokens/create-token/steel/api/src/sdk.rs

@@ -0,0 +1,27 @@
+use steel::*;
+
+use crate::prelude::*;
+
+pub fn create_token(
+    payer: PubKey,
+    mint_authority: PubKey,
+    token_name: String,
+    token_symbol: String,
+    token_uri: String,
+) -> Instruction {
+    let token_name: [u8; 32] = token_name
+        .as_bytes()
+        .try_into()
+        .expect("token_name must be 32 bytes");
+    let token_symbol: [u8; 8] = token_symbol
+        .as_bytes()
+        .try_into()
+        .expect("token_symbol must be 32 bytes");
+    let token_uri: [u8; 64] = token_uri
+        .as_bytes()
+        .try_into()
+        .expect("token_uri must be 32 bytes");
+
+    let mint_pda = PubKey::find_program_address(&[b"mint"], &crate::ID);
+    let metadata_pda = PubKey::find_program_address();
+}

+ 19 - 0
tokens/create-token/steel/program/Cargo.toml

@@ -0,0 +1,19 @@
+[package]
+name = "steel-program"
+version = "0.1.0"
+edition = "2021"
+
+[lib]
+crate-type = ["cdylib", "lib"]
+
+[dependencies]
+steel-api.workspace = true
+solana-program.workspace = true
+steel.workspace = true
+
+[dev-dependencies]
+bs64 = "0.1.2"
+rand = "0.8.5"
+solana-program-test = "1.18"
+solana-sdk = "1.18"
+tokio = { version = "1.35", features = ["full"] }

+ 21 - 0
tokens/create-token/steel/program/src/lib.rs

@@ -0,0 +1,21 @@
+mod token;
+
+use steel::*;
+use steel_api::prelude::*;
+use token::*;
+
+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::Create_Token => process_create_token(accounts, name, symbol)?,
+    }
+
+    Ok(())
+}
+
+entrypoint!(process_instruction);

+ 35 - 0
tokens/create-token/steel/program/src/token.rs

@@ -0,0 +1,35 @@
+use solana_program::{msg, program_pack::Pack};
+use spl_token::state::Mint;
+use steel::*;
+use steel_api::prelude::*;
+
+pub fn process_create_token(
+    accounts: &[AccountInfo],
+    name: String,
+    symbol: String,
+) -> ProgramResult {
+    let mint = Mint {
+        mint_authority: COption::Some(accounts[0].key.to_owned()),
+        supply: 0,
+        decimals: 2,
+        is_initialized: false,
+        freeze_authority: COption::None,
+    };
+
+    let mut data = vec![];
+    mint.pack_into_slice(&mut data);
+
+    let mut instruction = Instruction::new(
+        accounts[0].key.to_owned(),
+        vec![],
+        vec![AccountMeta::new_readonly(accounts[0].key.to_owned(), false)],
+        data,
+    );
+
+    let mut instruction_data = vec![];
+    instruction.pack_into_slice(&mut instruction_data);
+
+    msg!("Instruction data: {:?}", instruction_data);
+
+    Ok(())
+}

+ 45 - 0
tokens/create-token/steel/program/tests/test.rs

@@ -0,0 +1,45 @@
+use solana_program::hash::Hash;
+use solana_program_test::{processor, BanksClient, ProgramTest};
+use solana_sdk::{signature::Keypair, signer::Signer, transaction::Transaction};
+use steel::*;
+use steel_api::prelude::*;
+
+async fn setup() -> (BanksClient, Keypair, Hash) {
+    let mut program_test = ProgramTest::new(
+        "steel",
+        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;
+
+    // Submit initialize transaction.
+    let ix = initialize(payer.pubkey());
+    let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash);
+    let res = banks.process_transaction(tx).await;
+    assert!(res.is_ok());
+
+    // Verify counter was initialized.
+    let counter_address = counter_pda().0;
+    let counter_account = banks.get_account(counter_address).await.unwrap().unwrap();
+    let counter = Counter::try_from_bytes(&counter_account.data).unwrap();
+    assert_eq!(counter_account.owner, steel_api::ID);
+    assert_eq!(counter.value, 0);
+
+    // Submit add transaction.
+    let ix = add(payer.pubkey(), 42);
+    let tx = Transaction::new_signed_with_payer(&[ix], Some(&payer.pubkey()), &[&payer], blockhash);
+    let res = banks.process_transaction(tx).await;
+    assert!(res.is_ok());
+
+    // Verify counter was incremented.
+    let counter_account = banks.get_account(counter_address).await.unwrap().unwrap();
+    let counter = Counter::try_from_bytes(&counter_account.data).unwrap();
+    assert_eq!(counter.value, 42);
+}