Skip to content

Commit 559dc9c

Browse files
authored
Merge pull request #49 from ZYJLiu/main
Update anchor tokens examples
2 parents 17afe2e + 3fc0943 commit 559dc9c

File tree

48 files changed

+1349
-1617
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1349
-1617
lines changed

Cargo.lock

Lines changed: 243 additions & 86 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,29 @@
11
[features]
22
seeds = false
3-
[programs.devnet]
4-
create_token = "5yRmjtx87UJMJF4NEeqjpmgAu7MBJZACW6ksiCYqQxVh"
3+
skip-lint = false
4+
5+
[programs.localnet]
6+
create_token = "2B6MrsKB2pVq6W6tY8dJLcnSd3Uv1KE7yRaboBjdQoEX"
57

68
[registry]
7-
url = "https://anchor.projectserum.com"
9+
url = "https://api.apr.dev"
810

911
[provider]
10-
cluster = "devnet"
12+
cluster = "localnet"
1113
wallet = "~/.config/solana/id.json"
1214

1315
[scripts]
1416
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
17+
18+
[test]
19+
startup_wait = 5000
20+
shutdown_wait = 2000
21+
22+
[test.validator]
23+
bind_address = "0.0.0.0"
24+
url = "https://api.mainnet-beta.solana.com"
25+
ledger = ".anchor/test-ledger"
26+
rpc_port = 8899
27+
28+
[[test.validator.clone]]
29+
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
2-
"dependencies": {
3-
"@metaplex-foundation/mpl-token-metadata": "^2.5.2",
4-
"@project-serum/anchor": "^0.24.2"
5-
},
6-
"devDependencies": {
7-
"@types/bn.js": "^5.1.0",
8-
"@types/chai": "^4.3.0",
9-
"@types/mocha": "^9.0.0",
10-
"chai": "^4.3.4",
11-
"mocha": "^9.0.3",
12-
"ts-mocha": "^10.0.0",
13-
"typescript": "^4.3.5"
14-
}
2+
"dependencies": {
3+
"@coral-xyz/anchor": "^0.28.1-beta.2",
4+
"@metaplex-foundation/mpl-token-metadata": "^2.5.2"
5+
},
6+
"devDependencies": {
7+
"@types/bn.js": "^5.1.0",
8+
"@types/chai": "^4.3.0",
9+
"@types/mocha": "^9.0.0",
10+
"chai": "^4.3.4",
11+
"mocha": "^9.0.3",
12+
"ts-mocha": "^10.0.0",
13+
"typescript": "^4.3.5"
14+
}
1515
}

tokens/create-token/anchor/programs/create-token/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,5 @@ default = []
1717

1818
[dependencies]
1919
anchor-lang = "0.28.0"
20-
anchor-spl = "0.28.0"
21-
mpl-token-metadata = { version = "1.11", features = [ "no-entrypoint" ] }
20+
anchor-spl = { version = "0.28.0", features = ["metadata"] }
21+
mpl-token-metadata = { version = "1.13.1", features = ["no-entrypoint"] }
Lines changed: 51 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
11
#![allow(clippy::result_large_err)]
22

33
use {
4-
anchor_lang::{prelude::*, solana_program::program::invoke},
5-
anchor_spl::token,
6-
mpl_token_metadata::instruction as mpl_instruction,
4+
anchor_lang::prelude::*,
5+
anchor_spl::{
6+
metadata::{create_metadata_accounts_v3, CreateMetadataAccountsV3, Metadata},
7+
token::{Mint, Token},
8+
},
9+
mpl_token_metadata::{pda::find_metadata_account, state::DataV2},
710
};
811

9-
declare_id!("5yRmjtx87UJMJF4NEeqjpmgAu7MBJZACW6ksiCYqQxVh");
12+
declare_id!("2B6MrsKB2pVq6W6tY8dJLcnSd3Uv1KE7yRaboBjdQoEX");
1013

1114
#[program]
1215
pub mod create_token {
1316
use super::*;
1417

1518
pub fn create_token_mint(
1619
ctx: Context<CreateTokenMint>,
17-
token_title: String,
20+
token_name: String,
1821
token_symbol: String,
1922
token_uri: String,
2023
_token_decimals: u8,
@@ -24,33 +27,34 @@ pub mod create_token {
2427
"Metadata account address: {}",
2528
&ctx.accounts.metadata_account.key()
2629
);
27-
invoke(
28-
&mpl_instruction::create_metadata_accounts_v3(
29-
ctx.accounts.token_metadata_program.key(), // Program ID (the Token Metadata Program)
30-
ctx.accounts.metadata_account.key(), // Metadata account
31-
ctx.accounts.mint_account.key(), // Mint account
32-
ctx.accounts.mint_authority.key(), // Mint authority
33-
ctx.accounts.payer.key(), // Payer
34-
ctx.accounts.mint_authority.key(), // Update authority
35-
token_title, // Name
36-
token_symbol, // Symbol
37-
token_uri, // URI
38-
None, // Creators
39-
0, // Seller fee basis points
40-
true, // Update authority is signer
41-
false, // Is mutable
42-
None, // Collection
43-
None, // Uses
44-
None, // Collection Details
30+
31+
// Cross Program Invocation (CPI)
32+
// Invoking the create_metadata_account_v3 instruction on the token metadata program
33+
create_metadata_accounts_v3(
34+
CpiContext::new(
35+
ctx.accounts.token_metadata_program.to_account_info(),
36+
CreateMetadataAccountsV3 {
37+
metadata: ctx.accounts.metadata_account.to_account_info(),
38+
mint: ctx.accounts.mint_account.to_account_info(),
39+
mint_authority: ctx.accounts.payer.to_account_info(),
40+
update_authority: ctx.accounts.payer.to_account_info(),
41+
payer: ctx.accounts.payer.to_account_info(),
42+
system_program: ctx.accounts.system_program.to_account_info(),
43+
rent: ctx.accounts.rent.to_account_info(),
44+
},
4545
),
46-
&[
47-
ctx.accounts.metadata_account.to_account_info(),
48-
ctx.accounts.mint_account.to_account_info(),
49-
ctx.accounts.mint_authority.to_account_info(),
50-
ctx.accounts.payer.to_account_info(),
51-
ctx.accounts.mint_authority.to_account_info(),
52-
ctx.accounts.rent.to_account_info(),
53-
],
46+
DataV2 {
47+
name: token_name,
48+
symbol: token_symbol,
49+
uri: token_uri,
50+
seller_fee_basis_points: 0,
51+
creators: None,
52+
collection: None,
53+
uses: None,
54+
},
55+
false, // Is mutable
56+
true, // Update authority is signer
57+
None, // Collection details
5458
)?;
5559

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

62-
// The macros within the Account Context will create our
63-
// Mint account and initialize it as a Mint
64-
// We just have to do the metadata
65-
//
6666
#[derive(Accounts)]
67-
#[instruction(
68-
token_title: String,
69-
token_symbol: String,
70-
token_uri: String,
71-
token_decimals: u8,
72-
)]
67+
#[instruction(_token_decimals: u8)]
7368
pub struct CreateTokenMint<'info> {
74-
/// CHECK: We're about to create this with Metaplex
7569
#[account(mut)]
70+
pub payer: Signer<'info>,
71+
72+
/// CHECK: Address validated using constraint
73+
#[account(
74+
mut,
75+
address=find_metadata_account(&mint_account.key()).0
76+
)]
7677
pub metadata_account: UncheckedAccount<'info>,
78+
// Create new mint account
7779
#[account(
7880
init,
7981
payer = payer,
80-
mint::decimals = token_decimals,
81-
mint::authority = mint_authority.key(),
82+
mint::decimals = _token_decimals,
83+
mint::authority = payer.key(),
8284
)]
83-
pub mint_account: Account<'info, token::Mint>,
84-
pub mint_authority: SystemAccount<'info>,
85-
#[account(mut)]
86-
pub payer: Signer<'info>,
87-
pub rent: Sysvar<'info, Rent>,
85+
pub mint_account: Account<'info, Mint>,
86+
87+
pub token_metadata_program: Program<'info, Metadata>,
88+
pub token_program: Program<'info, Token>,
8889
pub system_program: Program<'info, System>,
89-
pub token_program: Program<'info, token::Token>,
90-
/// CHECK: Metaplex will check this
91-
pub token_metadata_program: UncheckedAccount<'info>,
90+
pub rent: Sysvar<'info, Rent>,
9291
}
Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,90 +1,91 @@
1-
import {
2-
PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID
3-
} from '@metaplex-foundation/mpl-token-metadata';
4-
import * as anchor from "@project-serum/anchor";
1+
import { PROGRAM_ID as TOKEN_METADATA_PROGRAM_ID } from "@metaplex-foundation/mpl-token-metadata";
2+
import * as anchor from "@coral-xyz/anchor";
3+
import { TOKEN_PROGRAM_ID } from "@coral-xyz/anchor/dist/cjs/utils/token";
54
import { CreateToken } from "../target/types/create_token";
6-
5+
import {
6+
PublicKey,
7+
Keypair,
8+
SYSVAR_RENT_PUBKEY,
9+
SystemProgram,
10+
} from "@solana/web3.js";
711

812
describe("Create Tokens", () => {
9-
1013
const provider = anchor.AnchorProvider.env();
1114
anchor.setProvider(provider);
1215
const payer = provider.wallet as anchor.Wallet;
1316
const program = anchor.workspace.CreateToken as anchor.Program<CreateToken>;
1417

15-
const tokenTitle = "Solana Gold";
16-
const tokenSymbol = "GOLDSOL";
17-
const tokenUri = "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json";
18+
const metadata = {
19+
name: "Solana Gold",
20+
symbol: "GOLDSOL",
21+
uri: "https://raw.githubusercontent.com/solana-developers/program-examples/new-examples/tokens/tokens/.assets/spl-token.json",
22+
};
1823

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

21-
const mintKeypair: anchor.web3.Keypair = anchor.web3.Keypair.generate();
22-
23-
const metadataAddress = (await anchor.web3.PublicKey.findProgramAddress(
28+
// Derive the PDA of the metadata account for the mint.
29+
const [metadataAddress] = PublicKey.findProgramAddressSync(
2430
[
2531
Buffer.from("metadata"),
2632
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
2733
mintKeypair.publicKey.toBuffer(),
2834
],
2935
TOKEN_METADATA_PROGRAM_ID
30-
))[0];
36+
);
3137

3238
// SPL Token default = 9 decimals
33-
//
34-
const sx = await program.methods.createTokenMint(
35-
tokenTitle, tokenSymbol, tokenUri, 9
36-
)
39+
const transactionSignature = await program.methods
40+
.createTokenMint(metadata.name, metadata.symbol, metadata.uri, 9)
3741
.accounts({
42+
payer: payer.publicKey,
3843
metadataAccount: metadataAddress,
3944
mintAccount: mintKeypair.publicKey,
40-
mintAuthority: payer.publicKey,
41-
payer: payer.publicKey,
42-
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
43-
systemProgram: anchor.web3.SystemProgram.programId,
44-
tokenProgram: anchor.utils.token.TOKEN_PROGRAM_ID,
45+
rent: SYSVAR_RENT_PUBKEY,
46+
systemProgram: SystemProgram.programId,
47+
tokenProgram: TOKEN_PROGRAM_ID,
4548
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
4649
})
47-
.signers([mintKeypair, payer.payer])
50+
.signers([mintKeypair])
4851
.rpc();
4952

5053
console.log("Success!");
51-
console.log(` Mint Address: ${mintKeypair.publicKey}`);
52-
console.log(` Tx Signature: ${sx}`);
54+
console.log(` Mint Address: ${mintKeypair.publicKey}`);
55+
console.log(` Transaction Signature: ${transactionSignature}`);
5356
});
5457

5558
it("Create an NFT!", async () => {
56-
57-
const mintKeypair: anchor.web3.Keypair = anchor.web3.Keypair.generate();
59+
// Generate new keypair to use as address for mint account.
60+
const mintKeypair = new Keypair();
5861

59-
const metadataAddress = (await anchor.web3.PublicKey.findProgramAddress(
62+
// Derive the PDA of the metadata account for the mint.
63+
const [metadataAddress] = PublicKey.findProgramAddressSync(
6064
[
6165
Buffer.from("metadata"),
6266
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
6367
mintKeypair.publicKey.toBuffer(),
6468
],
6569
TOKEN_METADATA_PROGRAM_ID
66-
))[0];
70+
);
6771

6872
// NFT default = 0 decimals
69-
//
70-
const sx = await program.methods.createTokenMint(
71-
tokenTitle, tokenSymbol, tokenUri, 0
72-
)
73+
const transactionSignature = await program.methods
74+
.createTokenMint(metadata.name, metadata.symbol, metadata.uri, 0)
7375
.accounts({
76+
payer: payer.publicKey,
7477
metadataAccount: metadataAddress,
7578
mintAccount: mintKeypair.publicKey,
76-
mintAuthority: payer.publicKey,
77-
payer: payer.publicKey,
78-
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
79-
systemProgram: anchor.web3.SystemProgram.programId,
80-
tokenProgram: anchor.utils.token.TOKEN_PROGRAM_ID,
79+
rent: SYSVAR_RENT_PUBKEY,
80+
systemProgram: SystemProgram.programId,
81+
tokenProgram: TOKEN_PROGRAM_ID,
8182
tokenMetadataProgram: TOKEN_METADATA_PROGRAM_ID,
8283
})
83-
.signers([mintKeypair, payer.payer])
84+
.signers([mintKeypair])
8485
.rpc();
8586

8687
console.log("Success!");
87-
console.log(` Mint Address: ${mintKeypair.publicKey}`);
88-
console.log(` Tx Signature: ${sx}`);
88+
console.log(` Mint Address: ${mintKeypair.publicKey}`);
89+
console.log(` Transaction Signature: ${transactionSignature}`);
8990
});
9091
});

tokens/nft-minter/anchor/Anchor.toml

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,26 @@
11
[features]
22
seeds = false
3-
[programs.devnet]
4-
nft_minter = "A6itasS5iqANkC9yrzP1HJPBnJxj9tC8G5TmJzQGogGG"
3+
skip-lint = false
54

6-
[registry]
7-
url = "https://anchor.projectserum.com"
5+
[programs.localnet]
6+
nft_minter = "3qHNM98iLTaQtwmj2NkViXnHZQjNBS5PTHT2AuPxHXYN"
87

98
[provider]
10-
cluster = "devnet"
9+
cluster = "localnet"
1110
wallet = "~/.config/solana/id.json"
1211

1312
[scripts]
1413
test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
14+
15+
[test]
16+
startup_wait = 5000
17+
shutdown_wait = 2000
18+
19+
[test.validator]
20+
bind_address = "0.0.0.0"
21+
url = "https://api.mainnet-beta.solana.com"
22+
ledger = ".anchor/test-ledger"
23+
rpc_port = 8899
24+
25+
[[test.validator.clone]]
26+
address = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"

tokens/nft-minter/anchor/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
[workspace]
2-
members = [
3-
"programs/*"
4-
]
2+
members = ["programs/*"]
53

64
[profile.release]
75
overflow-checks = true

0 commit comments

Comments
 (0)