Skip to content
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

Add tokens/create-token/steel #295

Closed
Closed
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
12 changes: 12 additions & 0 deletions tokens/create-token/steel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[workspace]
members = ["api","program"]
resolver = "2"

[workspace.dependencies]
solana-program = "1.18.17"
steel = {version = "2.1", features = ["spl"]}
bytemuck = "1.4"
num_enum = "0.7"
spl-token = { version = "4.0.0", features = [ "no-entrypoint" ] }
mpl-token-metadata = { version = "4.1.2" }
thiserror = "2.0.3"
16 changes: 16 additions & 0 deletions tokens/create-token/steel/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "create-token-steel-api"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "lib"]

[dependencies]
solana-program.workspace = true
steel.workspace = true
bytemuck.workspace = true
num_enum.workspace = true
spl-token.workspace = true
mpl-token-metadata.workspace = true
thiserror.workspace = true
10 changes: 10 additions & 0 deletions tokens/create-token/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("Failed to parse string from bytes")]
ParseError = 0,
}

error!(SteelError);
122 changes: 122 additions & 0 deletions tokens/create-token/steel/api/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
use {
crate::error::*,
mpl_token_metadata::{instructions as mpl_instruction, types::DataV2},
solana_program::{msg, program::invoke, program_pack::Pack, rent::Rent, system_instruction},
spl_token::state::Mint,
std::ffi::CStr,
steel::*,
};

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

instruction!(SteelInstruction, CreateToken);
// CreateToken instruction
#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct CreateToken {
pub token_name: [u8; 32], // Metaplex metadata name: 32 bytes max
pub token_symbol: [u8; 10], // Metaplex metadata symbol: 10 bytes max
pub token_uri: [u8; 256], // Metaplex metadata uri: 200 bytes max
pub decimals: u8,
}

impl CreateToken {
pub fn process(accounts: &[AccountInfo<'_>], data: &[u8]) -> ProgramResult {
let args = Self::try_from_bytes(data)?;

let [mint_account, mint_authority, metadata_account, payer, rent, system_program, token_program, token_metadata_program] =
accounts
else {
return Err(ProgramError::NotEnoughAccountKeys);
};

// First create the account for the Mint
//
msg!("Creating mint account...");
msg!("Mint: {}", mint_account.key);
invoke(
&system_instruction::create_account(
payer.key,
mint_account.key,
(Rent::get()?).minimum_balance(Mint::LEN),
Mint::LEN as u64,
token_program.key,
),
&[
mint_account.clone(),
payer.clone(),
system_program.clone(),
token_program.clone(),
],
)?;

// Now initialize that account as a Mint (standard Mint)
//
msg!("Initializing mint account...");
msg!("Mint: {}", mint_account.key);

initialize_mint(
mint_account,
mint_authority,
Some(mint_authority),
token_program,
rent,
args.decimals,
)?;

// Now create the account for that Mint's metadata
//
msg!("Creating metadata account...");
msg!("Metadata account address: {}", metadata_account.key);

let name = Self::str_from_bytes(&mut args.token_name.to_vec())?.to_string();
let symbol = Self::str_from_bytes(&mut args.token_symbol.to_vec())?.to_string();
let uri = Self::str_from_bytes(&mut args.token_uri.to_vec())?.to_string();

mpl_instruction::CreateMetadataAccountV3Cpi {
__program: token_metadata_program,
metadata: metadata_account,
mint: mint_account,
mint_authority,
payer,
update_authority: (mint_authority, true),
system_program,
rent: Some(rent),
__args: mpl_instruction::CreateMetadataAccountV3InstructionArgs {
data: DataV2 {
name,
symbol,
uri,
seller_fee_basis_points: 0,
creators: None,
collection: None,
uses: None,
},
is_mutable: true,
collection_details: None,
},
}
.invoke()?;

msg!("Token mint created successfully.");

Ok(())
}

fn str_from_bytes(bytes: &mut Vec<u8>) -> Result<&str, ProgramError> {
// add an extra null byte, in the case every position is occupied with a non-null byte
bytes.push(0);

// remove excess null bytes
if let Ok(cstr) = CStr::from_bytes_until_nul(bytes) {
if let Ok(str) = cstr.to_str() {
return Ok(str);
}
}
Err(SteelError::ParseError.into())
}
}
11 changes: 11 additions & 0 deletions tokens/create-token/steel/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
pub mod error;
pub mod instruction;

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

use steel::*;

declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35");
8 changes: 8 additions & 0 deletions tokens/create-token/steel/cicd.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

# This script is for quick building & deploying of the program.
# It also serves as a reference for the commands used for building & deploying Solana programs.
# Run this bad boy with "bash cicd.sh" or "./cicd.sh"

cargo build-sbf --manifest-path=./program/Cargo.toml
solana program deploy ./program/target/deploy/program.so
28 changes: 28 additions & 0 deletions tokens/create-token/steel/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"scripts": {
"test": "pnpm ts-mocha -p ./tsconfig.json -t 1000000 ./tests/test.ts",
"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/hello_solana_program.so",
"postinstall": "zx prepare.mjs"
},
"dependencies": {
"@metaplex-foundation/mpl-token-metadata": "^2.5.2",
"@solana/spl-token": "^0.4.9",
"@solana/web3.js": "^1.95.4",
"buffer": "^6.0.3"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.1",
"@types/mocha": "^10.0.9",
"@types/node": "^22.8.6",
"borsh": "0.7.0",
"chai": "^4.3.4",
"mocha": "^10.8.2",
"solana-bankrun": "^0.4.0",
"ts-mocha": "^10.0.0",
"typescript": "^5",
"zx": "^8.1.4"
}
}
Loading
Loading