Skip to content

Commit

Permalink
update anchor tokens examples
Browse files Browse the repository at this point in the history
  • Loading branch information
ZYJLiu committed Sep 8, 2023
1 parent 17afe2e commit 3fc0943
Show file tree
Hide file tree
Showing 48 changed files with 1,349 additions and 1,617 deletions.
329 changes: 243 additions & 86 deletions Cargo.lock

Large diffs are not rendered by default.

23 changes: 19 additions & 4 deletions tokens/create-token/anchor/Anchor.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,29 @@
[features]
seeds = false
[programs.devnet]
create_token = "5yRmjtx87UJMJF4NEeqjpmgAu7MBJZACW6ksiCYqQxVh"
skip-lint = false

[programs.localnet]
create_token = "2B6MrsKB2pVq6W6tY8dJLcnSd3Uv1KE7yRaboBjdQoEX"

[registry]
url = "https://anchor.projectserum.com"
url = "https://api.apr.dev"

[provider]
cluster = "devnet"
cluster = "localnet"
wallet = "~/.config/solana/id.json"

[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

[test]
startup_wait = 5000
shutdown_wait = 2000

[test.validator]
bind_address = "0.0.0.0"
url = "https://api.mainnet-beta.solana.com"
ledger = ".anchor/test-ledger"
rpc_port = 8899

[[test.validator.clone]]
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
26 changes: 13 additions & 13 deletions tokens/create-token/anchor/package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"dependencies": {
"@metaplex-foundation/mpl-token-metadata": "^2.5.2",
"@project-serum/anchor": "^0.24.2"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"chai": "^4.3.4",
"mocha": "^9.0.3",
"ts-mocha": "^10.0.0",
"typescript": "^4.3.5"
}
"dependencies": {
"@coral-xyz/anchor": "^0.28.1-beta.2",
"@metaplex-foundation/mpl-token-metadata": "^2.5.2"
},
"devDependencies": {
"@types/bn.js": "^5.1.0",
"@types/chai": "^4.3.0",
"@types/mocha": "^9.0.0",
"chai": "^4.3.4",
"mocha": "^9.0.3",
"ts-mocha": "^10.0.0",
"typescript": "^4.3.5"
}
}
4 changes: 2 additions & 2 deletions tokens/create-token/anchor/programs/create-token/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ default = []

[dependencies]
anchor-lang = "0.28.0"
anchor-spl = "0.28.0"
mpl-token-metadata = { version = "1.11", features = [ "no-entrypoint" ] }
anchor-spl = { version = "0.28.0", features = ["metadata"] }
mpl-token-metadata = { version = "1.13.1", features = ["no-entrypoint"] }
103 changes: 51 additions & 52 deletions tokens/create-token/anchor/programs/create-token/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
#![allow(clippy::result_large_err)]

use {
anchor_lang::{prelude::*, solana_program::program::invoke},
anchor_spl::token,
mpl_token_metadata::instruction as mpl_instruction,
anchor_lang::prelude::*,
anchor_spl::{
metadata::{create_metadata_accounts_v3, CreateMetadataAccountsV3, Metadata},
token::{Mint, Token},
},
mpl_token_metadata::{pda::find_metadata_account, state::DataV2},
};

declare_id!("5yRmjtx87UJMJF4NEeqjpmgAu7MBJZACW6ksiCYqQxVh");
declare_id!("2B6MrsKB2pVq6W6tY8dJLcnSd3Uv1KE7yRaboBjdQoEX");

#[program]
pub mod create_token {
use super::*;

pub fn create_token_mint(
ctx: Context<CreateTokenMint>,
token_title: String,
token_name: String,
token_symbol: String,
token_uri: String,
_token_decimals: u8,
Expand All @@ -24,33 +27,34 @@ pub mod create_token {
"Metadata account address: {}",
&ctx.accounts.metadata_account.key()
);
invoke(
&mpl_instruction::create_metadata_accounts_v3(
ctx.accounts.token_metadata_program.key(), // Program ID (the Token Metadata Program)
ctx.accounts.metadata_account.key(), // Metadata account
ctx.accounts.mint_account.key(), // Mint account
ctx.accounts.mint_authority.key(), // Mint authority
ctx.accounts.payer.key(), // Payer
ctx.accounts.mint_authority.key(), // Update authority
token_title, // Name
token_symbol, // Symbol
token_uri, // URI
None, // Creators
0, // Seller fee basis points
true, // Update authority is signer
false, // Is mutable
None, // Collection
None, // Uses
None, // Collection Details

// Cross Program Invocation (CPI)
// Invoking the create_metadata_account_v3 instruction on the token metadata program
create_metadata_accounts_v3(
CpiContext::new(
ctx.accounts.token_metadata_program.to_account_info(),
CreateMetadataAccountsV3 {
metadata: ctx.accounts.metadata_account.to_account_info(),
mint: ctx.accounts.mint_account.to_account_info(),
mint_authority: ctx.accounts.payer.to_account_info(),
update_authority: ctx.accounts.payer.to_account_info(),
payer: ctx.accounts.payer.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
rent: ctx.accounts.rent.to_account_info(),
},
),
&[
ctx.accounts.metadata_account.to_account_info(),
ctx.accounts.mint_account.to_account_info(),
ctx.accounts.mint_authority.to_account_info(),
ctx.accounts.payer.to_account_info(),
ctx.accounts.mint_authority.to_account_info(),
ctx.accounts.rent.to_account_info(),
],
DataV2 {
name: token_name,
symbol: token_symbol,
uri: token_uri,
seller_fee_basis_points: 0,
creators: None,
collection: None,
uses: None,
},
false, // Is mutable
true, // Update authority is signer
None, // Collection details
)?;

msg!("Token mint created successfully.");
Expand All @@ -59,34 +63,29 @@ pub mod create_token {
}
}

// The macros within the Account Context will create our
// Mint account and initialize it as a Mint
// We just have to do the metadata
//
#[derive(Accounts)]
#[instruction(
token_title: String,
token_symbol: String,
token_uri: String,
token_decimals: u8,
)]
#[instruction(_token_decimals: u8)]
pub struct CreateTokenMint<'info> {
/// CHECK: We're about to create this with Metaplex
#[account(mut)]
pub payer: Signer<'info>,

/// CHECK: Address validated using constraint
#[account(
mut,
address=find_metadata_account(&mint_account.key()).0
)]
pub metadata_account: UncheckedAccount<'info>,
// Create new mint account
#[account(
init,
payer = payer,
mint::decimals = token_decimals,
mint::authority = mint_authority.key(),
mint::decimals = _token_decimals,
mint::authority = payer.key(),
)]
pub mint_account: Account<'info, token::Mint>,
pub mint_authority: SystemAccount<'info>,
#[account(mut)]
pub payer: Signer<'info>,
pub rent: Sysvar<'info, Rent>,
pub mint_account: Account<'info, Mint>,

pub token_metadata_program: Program<'info, Metadata>,
pub token_program: Program<'info, Token>,
pub system_program: Program<'info, System>,
pub token_program: Program<'info, token::Token>,
/// CHECK: Metaplex will check this
pub token_metadata_program: UncheckedAccount<'info>,
pub rent: Sysvar<'info, Rent>,
}
83 changes: 42 additions & 41 deletions tokens/create-token/anchor/tests/test.ts
Original file line number Diff line number Diff line change
@@ -1,90 +1,91 @@
import {
PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID
} from '@metaplex-foundation/mpl-token-metadata';
import * as anchor from "@project-serum/anchor";
import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from "@metaplex-foundation/mpl-token-metadata";
import * as anchor from "@coral-xyz/anchor";
import { TOKEN_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
import { CreateToken } from "../target/types/create_token";

import {
PublicKey,
Keypair,
SYSVAR_RENT_PUBKEY,
SystemProgram,
} from "@solana/web3.js";

describe("Create Tokens", () => {

const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const payer = provider.wallet as anchor.Wallet;
const program = anchor.workspace.CreateToken as anchor.Program<CreateToken>;

const tokenTitle = "Solana Gold";
const tokenSymbol = "GOLDSOL";
const tokenUri = "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json";
const metadata = {
name: "Solana Gold",
symbol: "GOLDSOL",
uri: "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json",
};

it("Create an SPL Token!", async () => {
// Generate new keypair to use as address for mint account.
const mintKeypair = new Keypair();

const mintKeypair: anchor.web3.Keypair = anchor.web3.Keypair.generate();

const metadataAddress = (await anchor.web3.PublicKey.findProgramAddress(
// Derive the PDA of the metadata account for the mint.
const [metadataAddress] = PublicKey.findProgramAddressSync(
[
Buffer.from("metadata"),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mintKeypair.publicKey.toBuffer(),
],
TOKEN_METADATA_PROGRAM_ID
))[0];
);

// SPL Token default = 9 decimals
//
const sx = await program.methods.createTokenMint(
tokenTitle, tokenSymbol, tokenUri, 9
)
const transactionSignature = await program.methods
.createTokenMint(metadata.name, metadata.symbol, metadata.uri, 9)
.accounts({
payer: payer.publicKey,
metadataAccount: metadataAddress,
mintAccount: mintKeypair.publicKey,
mintAuthority: payer.publicKey,
payer: payer.publicKey,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
systemProgram: anchor.web3.SystemProgram.programId,
tokenProgram: anchor.utils.token.TOKEN_PROGRAM_ID,
rent: SYSVAR_RENT_PUBKEY,
systemProgram: SystemProgram.programId,
tokenProgram: TOKEN_PROGRAM_ID,
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
})
.signers([mintKeypair, payer.payer])
.signers([mintKeypair])
.rpc();

console.log("Success!");
console.log(` Mint Address: ${mintKeypair.publicKey}`);
console.log(` Tx Signature: ${sx}`);
console.log(` Mint Address: ${mintKeypair.publicKey}`);
console.log(` Transaction Signature: ${transactionSignature}`);
});

it("Create an NFT!", async () => {

const mintKeypair: anchor.web3.Keypair = anchor.web3.Keypair.generate();
// Generate new keypair to use as address for mint account.
const mintKeypair = new Keypair();

const metadataAddress = (await anchor.web3.PublicKey.findProgramAddress(
// Derive the PDA of the metadata account for the mint.
const [metadataAddress] = PublicKey.findProgramAddressSync(
[
Buffer.from("metadata"),
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
mintKeypair.publicKey.toBuffer(),
],
TOKEN_METADATA_PROGRAM_ID
))[0];
);

// NFT default = 0 decimals
//
const sx = await program.methods.createTokenMint(
tokenTitle, tokenSymbol, tokenUri, 0
)
const transactionSignature = await program.methods
.createTokenMint(metadata.name, metadata.symbol, metadata.uri, 0)
.accounts({
payer: payer.publicKey,
metadataAccount: metadataAddress,
mintAccount: mintKeypair.publicKey,
mintAuthority: payer.publicKey,
payer: payer.publicKey,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
systemProgram: anchor.web3.SystemProgram.programId,
tokenProgram: anchor.utils.token.TOKEN_PROGRAM_ID,
rent: SYSVAR_RENT_PUBKEY,
systemProgram: SystemProgram.programId,
tokenProgram: TOKEN_PROGRAM_ID,
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
})
.signers([mintKeypair, payer.payer])
.signers([mintKeypair])
.rpc();

console.log("Success!");
console.log(` Mint Address: ${mintKeypair.publicKey}`);
console.log(` Tx Signature: ${sx}`);
console.log(` Mint Address: ${mintKeypair.publicKey}`);
console.log(` Transaction Signature: ${transactionSignature}`);
});
});
22 changes: 17 additions & 5 deletions tokens/nft-minter/anchor/Anchor.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
[features]
seeds = false
[programs.devnet]
nft_minter = "A6itasS5iqANkC9yrzP1HJPBnJxj9tC8G5TmJzQGogGG"
skip-lint = false

[registry]
url = "https://anchor.projectserum.com"
[programs.localnet]
nft_minter = "3qHNM98iLTaQtwmj2NkViXnHZQjNBS5PTHT2AuPxHXYN"

[provider]
cluster = "devnet"
cluster = "localnet"
wallet = "~/.config/solana/id.json"

[scripts]
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"

[test]
startup_wait = 5000
shutdown_wait = 2000

[test.validator]
bind_address = "0.0.0.0"
url = "https://api.mainnet-beta.solana.com"
ledger = ".anchor/test-ledger"
rpc_port = 8899

[[test.validator.clone]]
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
4 changes: 1 addition & 3 deletions tokens/nft-minter/anchor/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
[workspace]
members = [
"programs/*"
]
members = ["programs/*"]

[profile.release]
overflow-checks = true
Expand Down
Loading

0 comments on commit 3fc0943

Please sign in to comment.