- Mint accounts uniquely represent a token on Solana and store its global metadata.
- Light mints are on-chain accounts like SPL mints, but the light token program sponsors the rent-exemption cost for you.
Light Rent Config Explained
Light Rent Config Explained
- The Light Token Program pays the rent-exemption cost for the account.
- Transaction fee payers bump a virtual rent balance when writing to the account, which keeps the account “hot”.
- “Cold” accounts virtual rent balance below threshold (eg 24h without write bump) get auto-compressed.
- The cold account’s state is cryptographically preserved on the Solana ledger. Users can load a cold account into hot state in-flight when using the account again.
- TypeScript Client
- Rust Client
- Program
createMintInterface is a unified interface that dispatches to different mint creation paths based on programId:TOKEN_PROGRAM_IDorTOKEN_2022_PROGRAM_ID→ delegates to SPL or T22createMint- Otherwise it defaults to
LIGHT_TOKEN_PROGRAM_ID→ creates a Light Token mint
Find the source code
here.
Create Mint with Token Metadata
Installation
Installation
- npm
- yarn
- pnpm
Install packages in your working directory:Install the CLI globally:
Report incorrect code
Copy
Ask AI
npm install @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Report incorrect code
Copy
Ask AI
npm install -g @lightprotocol/zk-compression-cli@beta
Install packages in your working directory:Install the CLI globally:
Report incorrect code
Copy
Ask AI
yarn add @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Report incorrect code
Copy
Ask AI
yarn global add @lightprotocol/zk-compression-cli@beta
Install packages in your working directory:Install the CLI globally:
Report incorrect code
Copy
Ask AI
pnpm add @lightprotocol/stateless.js@beta \
@lightprotocol/compressed-token@beta
Report incorrect code
Copy
Ask AI
pnpm add -g @lightprotocol/zk-compression-cli@beta
- Localnet
- Devnet
Report incorrect code
Copy
Ask AI
# start local test-validator in a separate terminal
light test-validator
In the code examples, use
createRpc() without arguments for localnet.Get an API key from Helius and add to
.env:.env
Report incorrect code
Copy
Ask AI
API_KEY=<your-helius-api-key>
In the code examples, use
createRpc(RPC_URL) with the devnet URL.The
mintAuthority must be a Signer for light-mints but can be just a
PublicKey for SPL/T22.- Action
- Instruction
Report incorrect code
Copy
Ask AI
import "dotenv/config";
import { Keypair } from "@solana/web3.js";
import { createRpc } from "@lightprotocol/stateless.js";
import { createMintInterface, createTokenMetadata } from "@lightprotocol/compressed-token";
import { homedir } from "os";
import { readFileSync } from "fs";
// devnet:
const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
const rpc = createRpc(RPC_URL);
// localnet:
// const rpc = createRpc();
const payer = Keypair.fromSecretKey(
new Uint8Array(
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8"))
)
);
(async function () {
const { mint, transactionSignature } = await createMintInterface(
rpc,
payer,
payer,
null,
9,
undefined,
undefined,
undefined,
createTokenMetadata("Example Token", "EXT", "https://example.com/metadata.json")
);
console.log("Mint:", mint.toBase58());
console.log("Tx:", transactionSignature);
})();
Report incorrect code
Copy
Ask AI
import "dotenv/config";
import {
Keypair,
ComputeBudgetProgram,
PublicKey,
Transaction,
sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
createRpc,
getBatchAddressTreeInfo,
selectStateTreeInfo,
CTOKEN_PROGRAM_ID,
} from "@lightprotocol/stateless.js";
import {
createMintInstruction,
createTokenMetadata,
} from "@lightprotocol/compressed-token";
import { homedir } from "os";
import { readFileSync } from "fs";
const COMPRESSED_MINT_SEED = Buffer.from("compressed_mint");
function findMintAddress(mintSigner: PublicKey): [PublicKey, number] {
return PublicKey.findProgramAddressSync(
[COMPRESSED_MINT_SEED, mintSigner.toBuffer()],
CTOKEN_PROGRAM_ID,
);
}
// devnet:
// const RPC_URL = `https://devnet.helius-rpc.com?api-key=${process.env.API_KEY!}`;
// const rpc = createRpc(RPC_URL);
// localnet:
const rpc = createRpc();
const payer = Keypair.fromSecretKey(
new Uint8Array(
JSON.parse(readFileSync(`${homedir()}/.config/solana/id.json`, "utf8")),
),
);
(async function () {
const mintSigner = Keypair.generate();
const addressTreeInfo = getBatchAddressTreeInfo();
const stateTreeInfo = selectStateTreeInfo(await rpc.getStateTreeInfos());
const [mintPda] = findMintAddress(mintSigner.publicKey);
const validityProof = await rpc.getValidityProofV2(
[],
[{ address: mintPda.toBytes(), treeInfo: addressTreeInfo }],
);
const ix = createMintInstruction(
mintSigner.publicKey,
9,
payer.publicKey,
null,
payer.publicKey,
validityProof,
addressTreeInfo,
stateTreeInfo,
createTokenMetadata(
"Example Token",
"EXT",
"https://example.com/metadata.json",
),
);
const tx = new Transaction().add(
ComputeBudgetProgram.setComputeUnitLimit({ units: 1_000_000 }),
ix,
);
const signature = await sendAndConfirmTransaction(rpc, tx, [
payer,
mintSigner,
]);
console.log("Mint:", mintPda.toBase58());
console.log("Tx:", signature);
})();
CreateMint creates an on-chain mint account that can optionally include token metadata.
The instruction also writes a compressed mint address to the address Merkle tree, which preserves the mint state when the on-chain account is compressed.Compare to SPL:Prerequisites
Dependencies
Dependencies
Cargo.toml
Report incorrect code
Copy
Ask AI
[dependencies]
light-token = "0.4.0"
light-client = { version = "0.19.0", features = ["v2"] }
solana-sdk = "2"
borsh = "0.10.4"
tokio = { version = "1", features = ["full"] }
Developer Environment
Developer Environment
- In-Memory (LightProgramTest)
- Localnet (LightClient)
- Devnet (LightClient)
Test with Lite-SVM (…)
Report incorrect code
Copy
Ask AI
# Initialize project
cargo init my-light-project
cd my-light-project
# Run tests
cargo test
Report incorrect code
Copy
Ask AI
use light_program_test::{LightProgramTest, ProgramTestConfig};
use solana_sdk::signer::Signer;
#[tokio::test]
async fn test_example() {
// In-memory test environment
let mut rpc = LightProgramTest::new(ProgramTestConfig::default())
.await
.unwrap();
let payer = rpc.get_payer().insecure_clone();
println!("Payer: {}", payer.pubkey());
}
Connects to a local test validator.
- npm
- yarn
- pnpm
Report incorrect code
Copy
Ask AI
npm install -g @lightprotocol/zk-compression-cli@beta
Report incorrect code
Copy
Ask AI
yarn global add @lightprotocol/zk-compression-cli@beta
Report incorrect code
Copy
Ask AI
pnpm add -g @lightprotocol/zk-compression-cli@beta
Report incorrect code
Copy
Ask AI
# Initialize project
cargo init my-light-project
cd my-light-project
# Start local test validator (in separate terminal)
light test-validator
Report incorrect code
Copy
Ask AI
use light_client::rpc::{LightClient, LightClientConfig, Rpc};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Connects to http://localhost:8899
let rpc = LightClient::new(LightClientConfig::local()).await?;
let slot = rpc.get_slot().await?;
println!("Current slot: {}", slot);
Ok(())
}
Replace
<your-api-key> with your actual API key. Get your API key here.Report incorrect code
Copy
Ask AI
use light_client::rpc::{LightClient, LightClientConfig, Rpc};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let rpc_url = "https://devnet.helius-rpc.com?api-key=<your_api_key>";
let rpc = LightClient::new(
LightClientConfig::new(rpc_url.to_string(), None, None)
).await?;
println!("Connected to Devnet");
Ok(())
}
Create Mint with Token Metadata
View the source code and full example with shared test utilities.
- Action
- Instruction
Report incorrect code
Copy
Ask AI
use light_client::rpc::Rpc;
use light_token_client::actions::{CreateMint, TokenMetadata};
use rust_client::setup_rpc_and_payer;
use solana_sdk::signer::Signer;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (mut rpc, payer) = setup_rpc_and_payer().await;
let (signature, mint) = CreateMint {
decimals: 9,
freeze_authority: None,
token_metadata: Some(TokenMetadata {
name: "Example Token".to_string(),
symbol: "EXT".to_string(),
uri: "https://example.com/metadata.json".to_string(),
update_authority: Some(payer.pubkey()),
additional_metadata: Some(vec![("type".to_string(), "example".to_string())]),
}),
seed: None,
}
.execute(&mut rpc, &payer, &payer)
.await?;
let data = rpc.get_account(mint).await?;
println!("Mint: {mint} exists: {} Tx: {signature}", data.is_some());
Ok(())
}
Report incorrect code
Copy
Ask AI
use light_client::{
indexer::{AddressWithTree, Indexer},
rpc::Rpc,
};
use light_program_test::{LightProgramTest, ProgramTestConfig};
use light_token::instruction::{
derive_mint_compressed_address, find_mint_address, CreateMint, CreateMintParams,
DEFAULT_RENT_PAYMENT, DEFAULT_WRITE_TOP_UP,
};
use light_token_interface::{
instructions::extensions::{
token_metadata::TokenMetadataInstructionData, ExtensionInstructionData,
},
state::AdditionalMetadata,
};
use solana_sdk::{signature::Keypair, signer::Signer};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut rpc = LightProgramTest::new(ProgramTestConfig::new_v2(false, None)).await?;
let payer = rpc.get_payer().insecure_clone();
let mint_seed = Keypair::new();
let decimals = 9u8;
// Get address tree to store compressed address for when mint turns inactive
// We must create a compressed address at creation to ensure the mint does not exist yet
let address_tree = rpc.get_address_tree_v2();
// Get state tree to store mint when inactive
let output_queue = rpc.get_random_state_tree_info().unwrap().queue;
// Derive mint addresses
let compression_address =
derive_mint_compressed_address(&mint_seed.pubkey(), &address_tree.tree);
let mint = find_mint_address(&mint_seed.pubkey()).0; // on-chain Mint PDA
// Fetch validity proof to proof address does not exist yet
let rpc_result = rpc
.get_validity_proof(
vec![],
vec![AddressWithTree {
address: compression_address,
tree: address_tree.tree,
}],
None,
)
.await
.unwrap()
.value;
// Build CreateMintParams with token metadata extension
let params = CreateMintParams {
decimals,
address_merkle_tree_root_index: rpc_result.addresses[0].root_index, // stores mint compressed address
mint_authority: payer.pubkey(),
proof: rpc_result.proof.0.unwrap(),
compression_address, // address for compression when mint turns inactive
mint,
bump: find_mint_address(&mint_seed.pubkey()).1,
freeze_authority: None,
extensions: Some(vec![ExtensionInstructionData::TokenMetadata(
TokenMetadataInstructionData {
update_authority: Some(payer.pubkey().to_bytes().into()),
name: b"Example Token".to_vec(),
symbol: b"EXT".to_vec(),
uri: b"https://example.com/metadata.json".to_vec(),
additional_metadata: Some(vec![AdditionalMetadata {
key: b"type".to_vec(),
value: b"example".to_vec(),
}]),
},
)]),
rent_payment: DEFAULT_RENT_PAYMENT, // 24h of rent
write_top_up: DEFAULT_WRITE_TOP_UP, // 3h of rent
};
// Build and send instruction (mint_seed must sign)
let create_mint_instruction = CreateMint::new(
params,
mint_seed.pubkey(),
payer.pubkey(),
address_tree.tree,
output_queue,
)
.instruction()?;
let sig = rpc
.create_and_send_transaction(&[create_mint_instruction], &payer.pubkey(), &[&payer, &mint_seed])
.await?;
let data = rpc.get_account(mint).await?;
println!("Mint: {} exists: {} Tx: {sig}", mint, data.is_some());
Ok(())
}
- CPI
- Anchor Macros
Compare to SPL:
- Mint
- With Token Metadata
Configure Token Metadata
Report incorrect code
Copy
Ask AI
use light_token_interface::instructions::extensions::{
token_metadata::TokenMetadataInstructionData, ExtensionInstructionData,
};
let extensions = Some(vec![ExtensionInstructionData::TokenMetadata(
TokenMetadataInstructionData {
update_authority: Some(authority.key.to_bytes().into()),
name: b"Example Token".to_vec(),
symbol: b"EXT".to_vec(),
uri: b"https://example.com/metadata.json".to_vec(),
additional_metadata: None,
},
)]);
Fields must be set at light-mint creation. Standard fields (
name,
symbol, uri) can be updated by update_authority. For
additional_metadata, only existing keys can be modified or removed. New keys
cannot be added after creation.Configure Mint
Configure mint parameters includingdecimals, authorities, rent settings, and pass extensions from the previous step.Report incorrect code
Copy
Ask AI
use light_token::instruction::CreateMintParams;
let params = CreateMintParams {
decimals,
address_merkle_tree_root_index,
mint_authority: *ctx.accounts.authority.key,
proof,
compression_address,
mint,
bump,
freeze_authority,
extensions,
rent_payment: rent_payment.unwrap_or(16), // ~24 hours rent
write_top_up: write_top_up.unwrap_or(766), // ~3 hours rent
};
The address of the mint account is stored in an address Merkle tree
, which is maintained by the protocol.
The client passes a validity proof that proves the mint address does not
exist yet.
System Accounts
Include system accounts such as the Light System Program to verify the proof and write the mint address to the address tree.System Accounts List
System Accounts List
| Account | Description | |
|---|---|---|
| 1 | Verifies validity proofs and executes compressed account state transitions. | |
| 2 | CPI Authority PDA | PDA that authorizes CPIs from the Light Token Program to the Light System Program. |
| 3 | Registered Program PDA | Proves the Light Token Program is registered to use compression. |
| 4 | Signs CPI calls from the Light System Program to the Account Compression Program. | |
| 5 | Writes to state and address Merkle tree accounts. | |
| 6 | Solana System Program. |
Report incorrect code
Copy
Ask AI
use light_token::instruction::SystemAccountInfos;
let system_accounts = SystemAccountInfos {
light_system_program: ctx.accounts.light_system_program.to_account_info(),
cpi_authority_pda: ctx.accounts.cpi_authority_pda.to_account_info(),
registered_program_pda: ctx.accounts.registered_program_pda.to_account_info(),
account_compression_authority: ctx.accounts.account_compression_authority.to_account_info(),
account_compression_program: ctx.accounts.account_compression_program.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
};
Build Account Infos and CPI the Light Token Program
Useinvoke or invoke_signed:- When
mint_seedis an external keypair, useinvoke. - When
mint_seedis a PDA, useinvoke_signedwith its seeds. - When both
mint_seedandauthorityare PDAs, useinvoke_signedwith both seeds.
- invoke (External signer)
- invoke_signed (PDA mint seed)
- invoke_signed (Two PDA signers)
Report incorrect code
Copy
Ask AI
use light_token::instruction::CreateMintCpi;
CreateMintCpi::new(
mint_seed.clone(),
authority.clone(),
payer.clone(),
address_tree.clone(), // stores address
output_queue.clone(), // stores account when inactive
compressible_config.clone(), // rent settings
mint.clone(),
rent_sponsor.clone(),
system_accounts,
params,
)
.invoke()
Report incorrect code
Copy
Ask AI
use light_token::instruction::CreateMintCpi;
let signer_seeds: &[&[u8]] = &[MINT_SIGNER_SEED, &[bump]];
CreateMintCpi::new(
mint_seed.clone(),
authority.clone(),
payer.clone(),
address_tree.clone(),
output_queue.clone(),
compressible_config.clone(),
mint.clone(),
rent_sponsor.clone(),
system_accounts,
params,
)
.invoke_signed(&[signer_seeds])
Report incorrect code
Copy
Ask AI
use light_token::instruction::CreateMintCpi;
let mint_seed_seeds: &[&[u8]] = &[MINT_SIGNER_SEED, &[mint_seed_bump]];
let authority_seeds: &[&[u8]] = &[MINT_AUTHORITY_SEED, &[authority_bump]];
CreateMintCpi::new(
mint_seed.clone(),
authority.clone(),
payer.clone(),
address_tree.clone(),
output_queue.clone(),
compressible_config.clone(),
mint.clone(),
rent_sponsor.clone(),
system_accounts,
params,
)
.invoke_signed(&[mint_seed_seeds, authority_seeds])
Full Code Example
- Anchor
View the source code and full example with shared test utilities.
Report incorrect code
Copy
Ask AI
#![allow(unexpected_cfgs, deprecated)]
use anchor_lang::prelude::*;
use light_token::instruction::{
CreateMintCpi, CreateMintParams, SystemAccountInfos, DEFAULT_RENT_PAYMENT, DEFAULT_WRITE_TOP_UP,
};
use light_token::{CompressedProof, ExtensionInstructionData, TokenMetadataInstructionData};
declare_id!("A1rJEoepgKYWZYZ8KVFpxgeeRGwBrU7xk8S39srjVkUX");
/// Token metadata parameters for creating a mint with metadata.
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct TokenMetadataParams {
pub name: Vec<u8>,
pub symbol: Vec<u8>,
pub uri: Vec<u8>,
pub update_authority: Option<Pubkey>,
}
#[program]
pub mod light_token_anchor_create_mint {
use super::*;
pub fn create_mint(
ctx: Context<CreateMintAccounts>,
decimals: u8,
address_merkle_tree_root_index: u16,
compression_address: [u8; 32],
proof: CompressedProof,
freeze_authority: Option<Pubkey>,
bump: u8,
rent_payment: Option<u8>,
write_top_up: Option<u32>,
metadata: Option<TokenMetadataParams>,
) -> Result<()> {
let mint = light_token::instruction::find_mint_address(ctx.accounts.mint_seed.key).0;
let extensions = metadata.map(|m| {
vec![ExtensionInstructionData::TokenMetadata(
TokenMetadataInstructionData {
update_authority: m
.update_authority
.map(|p| p.to_bytes().into()),
name: m.name,
symbol: m.symbol,
uri: m.uri,
additional_metadata: None,
},
)]
});
let params = CreateMintParams {
decimals,
address_merkle_tree_root_index,
mint_authority: *ctx.accounts.authority.key,
proof,
compression_address,
mint,
bump,
freeze_authority,
extensions,
rent_payment: rent_payment.unwrap_or(DEFAULT_RENT_PAYMENT),
write_top_up: write_top_up.unwrap_or(DEFAULT_WRITE_TOP_UP),
};
let system_accounts = SystemAccountInfos {
light_system_program: ctx.accounts.light_system_program.to_account_info(),
cpi_authority_pda: ctx.accounts.cpi_authority_pda.to_account_info(),
registered_program_pda: ctx.accounts.registered_program_pda.to_account_info(),
account_compression_authority: ctx.accounts.account_compression_authority.to_account_info(),
account_compression_program: ctx.accounts.account_compression_program.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
};
CreateMintCpi {
mint_seed: ctx.accounts.mint_seed.to_account_info(),
authority: ctx.accounts.authority.to_account_info(),
payer: ctx.accounts.payer.to_account_info(),
address_tree: ctx.accounts.address_tree.to_account_info(),
output_queue: ctx.accounts.output_queue.to_account_info(),
compressible_config: ctx.accounts.compressible_config.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
rent_sponsor: ctx.accounts.rent_sponsor.to_account_info(),
system_accounts,
cpi_context: None,
cpi_context_account: None,
params,
}
.invoke()?;
Ok(())
}
}
#[derive(Accounts)]
pub struct CreateMintAccounts<'info> {
/// CHECK: Light token program for CPI
pub light_token_program: AccountInfo<'info>,
pub mint_seed: Signer<'info>,
/// CHECK: Validated by light-token CPI
pub authority: AccountInfo<'info>,
#[account(mut)]
pub payer: Signer<'info>,
/// CHECK: Validated by light-token CPI
#[account(mut)]
pub address_tree: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI
#[account(mut)]
pub output_queue: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI
pub light_system_program: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI
pub cpi_authority_pda: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI
pub registered_program_pda: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI
pub account_compression_authority: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI
pub account_compression_program: AccountInfo<'info>,
pub system_program: Program<'info, System>,
/// CHECK: Validated by light-token CPI - use light_token::token::config_pda()
pub compressible_config: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI - derived from find_mint_address(mint_seed)
#[account(mut)]
pub mint: AccountInfo<'info>,
/// CHECK: Validated by light-token CPI - use light_token::token::rent_sponsor_pda()
#[account(mut)]
pub rent_sponsor: AccountInfo<'info>,
}
Compare to SPL:
- Mint
- With Token Metadata
Dependencies
Report incorrect code
Copy
Ask AI
[dependencies]
light-sdk = { version = "0.18.0", features = ["anchor", "v2", "cpi-context"] }
light-sdk-macros = "0.18.0"
light-compressible = "0.1.0"
anchor-lang = "0.31"
Program
Add#[light_program] above #[program]:Report incorrect code
Copy
Ask AI
use light_sdk_macros::light_program;
#[light_program]
#[program]
pub mod my_program {
use super::*;
pub fn create_mint<'info>(
ctx: Context<'_, '_, '_, 'info, CreateMint<'info>>,
params: CreateMintParams,
) -> Result<()> {
Ok(())
}
}
Accounts struct
DeriveLightAccounts on your Accounts struct and add #[light_account(...)] next to #[account(...)].- Mint
- Mint with metadata
Report incorrect code
Copy
Ask AI
/// CHECK: Validated by light-token CPI
#[account(mut)]
#[light_account(init,
mint::signer = mint_signer,
mint::authority = fee_payer,
mint::decimals = 9,
mint::seeds = &[MINT_SIGNER_SEED, self.authority.to_account_info().key.as_ref()],
mint::bump = params.mint_signer_bump
)]
pub mint: UncheckedAccount<'info>,
Report incorrect code
Copy
Ask AI
/// CHECK: Validated by light-token CPI
#[account(mut)]
#[light_account(init,
mint::signer = mint_signer,
mint::authority = fee_payer,
mint::decimals = 9,
mint::seeds = &[MINT_SIGNER_SEED, self.authority.to_account_info().key.as_ref()],
mint::bump = params.mint_signer_bump,
mint::name = params.name.clone(),
mint::symbol = params.symbol.clone(),
mint::uri = params.uri.clone(),
mint::update_authority = authority,
mint::additional_metadata = params.additional_metadata.clone()
)]
pub mint: UncheckedAccount<'info>,
Full code example
View the source code and full example with shared test utilities.
Report incorrect code
Copy
Ask AI
#![allow(deprecated)]
use anchor_lang::prelude::*;
use light_compressible::CreateAccountsProof;
use light_sdk::derive_light_cpi_signer;
use light_sdk_macros::{light_program, LightAccounts};
use light_sdk_types::CpiSigner;
declare_id!("HVmVqSJyMejBeUigePMSfX4aENJzCGHNxAJuT2PDMPRx");
pub const LIGHT_CPI_SIGNER: CpiSigner =
derive_light_cpi_signer!("HVmVqSJyMejBeUigePMSfX4aENJzCGHNxAJuT2PDMPRx");
pub const MINT_SIGNER_SEED: &[u8] = b"mint_signer";
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct CreateMintParams {
pub create_accounts_proof: CreateAccountsProof,
pub mint_signer_bump: u8,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone)]
pub struct CreateMintWithMetadataParams {
pub create_accounts_proof: CreateAccountsProof,
pub mint_signer_bump: u8,
pub name: Vec<u8>,
pub symbol: Vec<u8>,
pub uri: Vec<u8>,
}
#[derive(Accounts, LightAccounts)]
#[instruction(params: CreateMintParams)]
pub struct CreateMint<'info> {
#[account(mut)]
pub fee_payer: Signer<'info>,
pub authority: Signer<'info>,
/// CHECK: PDA derived from authority
#[account(
seeds = [MINT_SIGNER_SEED, authority.key().as_ref()],
bump,
)]
pub mint_signer: UncheckedAccount<'info>,
/// CHECK: Initialized by light_mint CPI
#[account(mut)]
#[light_account(init,
mint::signer = mint_signer,
mint::authority = fee_payer,
mint::decimals = 9,
mint::seeds = &[MINT_SIGNER_SEED, self.authority.to_account_info().key.as_ref()],
mint::bump = params.mint_signer_bump
)]
pub mint: UncheckedAccount<'info>,
/// CHECK: Compression config PDA
pub compression_config: AccountInfo<'info>,
/// CHECK: Light Token compressible config
pub light_token_compressible_config: AccountInfo<'info>,
/// CHECK: Rent sponsor
#[account(mut)]
pub rent_sponsor: AccountInfo<'info>,
/// CHECK: Light Token program
pub light_token_program: AccountInfo<'info>,
/// CHECK: Light Token CPI authority
pub light_token_cpi_authority: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
#[derive(Accounts, LightAccounts)]
#[instruction(params: CreateMintWithMetadataParams)]
pub struct CreateMintWithMetadata<'info> {
#[account(mut)]
pub fee_payer: Signer<'info>,
pub authority: Signer<'info>,
/// CHECK: PDA derived from authority
#[account(
seeds = [MINT_SIGNER_SEED, authority.key().as_ref()],
bump,
)]
pub mint_signer: UncheckedAccount<'info>,
/// CHECK: Initialized by light_mint CPI
#[account(mut)]
#[light_account(init,
mint::signer = mint_signer,
mint::authority = fee_payer,
mint::decimals = 9,
mint::seeds = &[MINT_SIGNER_SEED, self.authority.to_account_info().key.as_ref()],
mint::bump = params.mint_signer_bump,
mint::name = params.name.clone(),
mint::symbol = params.symbol.clone(),
mint::uri = params.uri.clone(),
mint::update_authority = authority
)]
pub mint: UncheckedAccount<'info>,
/// CHECK: Compression config PDA
pub compression_config: AccountInfo<'info>,
/// CHECK: Light Token compressible config
pub light_token_compressible_config: AccountInfo<'info>,
/// CHECK: Rent sponsor
#[account(mut)]
pub rent_sponsor: AccountInfo<'info>,
/// CHECK: Light Token program
pub light_token_program: AccountInfo<'info>,
/// CHECK: Light Token CPI authority
pub light_token_cpi_authority: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
#[light_program]
#[program]
pub mod light_token_macro_create_mint {
use super::*;
#[allow(unused_variables)]
pub fn create_mint<'info>(
ctx: Context<'_, '_, '_, 'info, CreateMint<'info>>,
params: CreateMintParams,
) -> Result<()> {
Ok(())
}
#[allow(unused_variables)]
pub fn create_mint_with_metadata<'info>(
ctx: Context<'_, '_, '_, 'info, CreateMintWithMetadata<'info>>,
params: CreateMintWithMetadataParams,
) -> Result<()> {
Ok(())
}
}