Skip to content

Commit

Permalink
fix create fungible decimals and optionally create ata
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelvanderwaal committed Dec 23, 2023
1 parent dda0740 commit 33c7d6e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 2 deletions.
13 changes: 12 additions & 1 deletion src/create/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use solana_sdk::signature::read_keypair_file;
use spl_associated_token_account::get_associated_token_address;
use spl_token::instruction::mint_to;

use crate::utils::create_token_if_missing_instruction;

use super::*;

pub struct CreateMetadataArgs {
Expand Down Expand Up @@ -127,7 +129,7 @@ pub fn create_fungible(args: CreateFungibleArgs) -> Result<()> {
collection: None,
uses: None,
collection_details: None,
decimals: None,
decimals: Some(args.decimals),
rule_set: None,
print_supply: None,
};
Expand All @@ -150,6 +152,15 @@ pub fn create_fungible(args: CreateFungibleArgs) -> Result<()> {
// Derive associated token account
let assoc = get_associated_token_address(&keypair.pubkey(), &mint.pubkey());

// Create associated token account if needed
instructions.push(create_token_if_missing_instruction(
&keypair.pubkey(),
&assoc,
&mint.pubkey(),
&keypair.pubkey(),
&assoc,
));

// Mint to instruction
let mint_to_ix = mint_to(
&spl_token::ID,
Expand Down
54 changes: 53 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
use anyhow::{anyhow, Result};
use borsh::{BorshDeserialize, BorshSerialize};
use retry::{delay::Exponential, retry};
use serde::Deserialize;
use serde_json::json;
use solana_client::rpc_request::RpcRequest;
use solana_client::{nonblocking::rpc_client::RpcClient as AsyncRpcClient, rpc_client::RpcClient};
use solana_program::instruction::AccountMeta;
use solana_program::program_pack::Pack;
use solana_program::pubkey::Pubkey;
use solana_program::system_program;
use solana_program::{pubkey, pubkey::Pubkey};
use solana_sdk::commitment_config::CommitmentConfig;
use solana_sdk::{
instruction::Instruction, signature::Keypair, signer::Signer, transaction::Transaction,
Expand Down Expand Up @@ -300,3 +303,52 @@ struct TokenAccount {
// #[serde(rename = "uiAmountString")]
// ui_amount_string: String,
}

const MPL_TOOLBOX_ID: Pubkey = pubkey!("TokExjvjJmhKaRBShsBAsbSvEWMA1AgUNK7ps4SAc2p");

#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
#[rustfmt::skip]
pub enum TokenExtrasInstruction {
/// Creates a new associated token account for the given mint and owner, if and only if
/// the given token account does not exists and the token account is the same as the
/// associated token account. That way, clients can ensure that, after this instruction,
/// the token account will exists.
///
/// Notice this instruction asks for both the token account and the associated token account (ATA)
/// These may or may not be the same account. Here are all the possible cases:
///
/// - Token exists and Token is ATA: Instruction succeeds.
/// - Token exists and Token is not ATA: Instruction succeeds.
/// - Token does not exist and Token is ATA: Instruction creates the ATA account and succeeds.
/// - Token does not exist and Token is not ATA: Instruction fails as we cannot create a
/// non-ATA account without it being a signer.
///
/// Note that additional checks are made to ensure that the token account provided
/// matches the mint account and owner account provided.
CreateTokenIfMissing,
}

pub fn create_token_if_missing_instruction(
payer: &Pubkey,
token: &Pubkey,
mint: &Pubkey,
owner: &Pubkey,
ata: &Pubkey,
) -> Instruction {
Instruction {
program_id: MPL_TOOLBOX_ID,
accounts: vec![
AccountMeta::new(*payer, true),
AccountMeta::new_readonly(*token, false),
AccountMeta::new_readonly(*mint, false),
AccountMeta::new_readonly(*owner, false),
AccountMeta::new(*ata, false),
AccountMeta::new_readonly(system_program::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
AccountMeta::new_readonly(spl_associated_token_account::id(), false),
],
data: TokenExtrasInstruction::CreateTokenIfMissing
.try_to_vec()
.unwrap(),
}
}

0 comments on commit 33c7d6e

Please sign in to comment.