Skip to main content

spl_forge/commands/
create.rs

1use crate::cli::{CreateArgs, CreateCommand};
2use crate::client::SplForgeClient;
3use crate::common::theme;
4use anyhow::{Context, Result};
5use solana_sdk::{pubkey::Pubkey, signer::Signer};
6use std::str::FromStr;
7
8/// Main handler for all `create` subcommands.
9pub async fn handle_create(args: CreateArgs) -> Result<()> {
10    let client = SplForgeClient::new().context("Failed to initialize client from config")?;
11
12    match args.command {
13        CreateCommand::Mint {
14            mint_authority,
15            freeze_authority,
16            decimals,
17            initial_supply,
18        } => {
19            let mint_authority =
20                Pubkey::from_str(&mint_authority).context("Invalid --mint-authority public key")?;
21            let freeze_authority = freeze_authority
22                .map(|value| Pubkey::from_str(&value).context("Invalid --freeze-authority public key"))
23                .transpose()?;
24
25            println!("{}", theme::action("Creating mint..."));
26            let mint_pubkey = client
27                .create_mint_account(decimals, mint_authority, freeze_authority)
28                .context("Failed to create mint account")?;
29
30            println!("{} {}", theme::success("Mint Address:"), mint_pubkey);
31
32            if initial_supply > 0 {
33                if mint_authority != client.signer.pubkey() {
34                    println!(
35                        "{}",
36                        theme::warning(
37                            "Initial supply not minted because signer is not the mint authority."
38                        )
39                    );
40                    println!(
41                        "{}",
42                        theme::warning(
43                            "Use the mint authority keypair in config to mint initial supply."
44                        )
45                    );
46                } else {
47                    client
48                        .mint_to(mint_pubkey, initial_supply)
49                        .context("Failed to mint initial supply")?;
50                    println!(
51                        "{} {}",
52                        theme::success("Minted initial supply:"),
53                        initial_supply
54                    );
55                }
56            }
57
58            Ok(())
59        }
60        CreateCommand::Metadata {
61            mint_address,
62            name,
63            symbol,
64            uri,
65            immutable,
66        } => {
67            let mint =
68                Pubkey::from_str(&mint_address).context("Invalid --mint-address public key")?;
69
70            println!("{}", theme::action("Creating metadata..."));
71            client
72                .create_metadata_account(mint, name, symbol, uri, !immutable)
73                .context("Failed to create metadata account")?;
74
75            println!("{} {}", theme::success("Metadata created for mint:"), mint);
76            Ok(())
77        }
78        CreateCommand::Token {
79            name,
80            symbol,
81            decimals,
82            uri,
83            initial_supply,
84            freeze_authority,
85            immutable,
86        } => {
87            let freeze_authority = freeze_authority
88                .map(|value| Pubkey::from_str(&value).context("Invalid --freeze-authority public key"))
89                .transpose()?;
90
91            println!("{}", theme::action("[1/3] Creating token mint..."));
92            let mint_pubkey = client
93                .create_mint_account(decimals, client.signer.pubkey(), freeze_authority)
94                .context("Failed to create token mint")?;
95
96            println!("{} {}", theme::success("Mint Address:"), mint_pubkey);
97
98            println!("{}", theme::action("[2/3] Creating token metadata..."));
99            client
100                .create_metadata_account(mint_pubkey, name, symbol, uri, !immutable)
101                .context("Failed to create token metadata")?;
102
103            if initial_supply > 0 {
104                println!("{}", theme::action("[3/3] Minting initial supply..."));
105                client
106                    .mint_to(mint_pubkey, initial_supply)
107                    .context("Failed to mint initial token supply")?;
108                println!(
109                    "{} {} {}",
110                    theme::success("Minted"),
111                    initial_supply,
112                    theme::success("tokens to signer wallet.")
113                );
114            } else {
115                println!(
116                    "{}",
117                    theme::warning(
118                        "[3/3] Skipping initial supply mint because --initial-supply is 0."
119                    )
120                );
121            }
122
123            println!("{}", theme::success("Token creation complete."));
124            Ok(())
125        }
126        CreateCommand::Nft {
127            name,
128            symbol,
129            uri,
130            immutable,
131            freeze_authority,
132            collection_mint,
133        } => {
134            let freeze_authority = freeze_authority
135                .map(|value| Pubkey::from_str(&value).context("Invalid --freeze-authority public key"))
136                .transpose()?;
137
138            if let Some(collection) = collection_mint {
139                println!(
140                    "{} {}",
141                    theme::warning("Collection mint support is not implemented yet. Ignoring:"),
142                    collection
143                );
144            }
145
146            println!("{}", theme::action("[1/4] Creating NFT mint..."));
147            let mint_pubkey = client
148                .create_mint_account(0, client.signer.pubkey(), freeze_authority)
149                .context("Failed to create NFT mint")?;
150
151            println!("{} {}", theme::success("NFT Mint Address:"), mint_pubkey);
152
153            println!("{}", theme::action("[2/4] Creating NFT metadata..."));
154            client
155                .create_metadata_account(mint_pubkey, name, symbol, uri, !immutable)
156                .context("Failed to create NFT metadata")?;
157
158            println!("{}", theme::action("[3/4] Minting NFT to signer wallet..."));
159            client
160                .mint_to(mint_pubkey, 1)
161                .context("Failed to mint NFT")?;
162
163            println!("{}", theme::action("[4/4] Revoking mint authority..."));
164            client
165                .revoke_mint_authority(mint_pubkey)
166                .context("Failed to revoke NFT mint authority")?;
167
168            println!("{}", theme::success("NFT creation complete."));
169            Ok(())
170        }
171        _ => {
172            println!(
173                "{}",
174                theme::warning(
175                    "This create subcommand is not implemented yet. Market, pool, and launch are coming later."
176                )
177            );
178            Ok(())
179        }
180    }
181}