Skip to content

Commit 90b5c46

Browse files
committed
Copy token code from professional-education into project-3-tokens
1 parent c6dce45 commit 90b5c46

File tree

4 files changed

+218
-0
lines changed

4 files changed

+218
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// This uses "@metaplex-foundation/mpl-token-metadata@2" to create tokens
2+
import "dotenv/config";
3+
import {
4+
getKeypairFromEnvironment,
5+
getExplorerLink,
6+
} from "@solana-developers/helpers";
7+
import {
8+
Connection,
9+
clusterApiUrl,
10+
PublicKey,
11+
Transaction,
12+
sendAndConfirmTransaction,
13+
} from "@solana/web3.js";
14+
import {
15+
DataV2,
16+
createCreateMetadataAccountV3Instruction,
17+
} from "@metaplex-foundation/mpl-token-metadata";
18+
19+
const user = getKeypairFromEnvironment("SECRET_KEY");
20+
21+
const connection = new Connection(clusterApiUrl("devnet"));
22+
23+
console.log(
24+
`🔑 We've loaded our keypair securely, using an env file! Our public key is: ${user.publicKey.toBase58()}`
25+
);
26+
27+
const TOKEN_METADATA_PROGRAM_ID = new PublicKey(
28+
"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s"
29+
);
30+
31+
// Subtitute in your token mint account
32+
const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE");
33+
34+
const metadataData: DataV2 = {
35+
name: "Solana Training Token",
36+
symbol: "TRAINING",
37+
// An off-chain link to more information about the token using Metaplex standard for off-chain data
38+
// We are using a GitHub link here, but in production this content would be hosted on an immutable storage like
39+
// Arweave / IPFS / Pinata etc
40+
uri: "https://raw.githubusercontent.com/solana-developers/professional-education/main/labs/sample-token-metadata.json",
41+
sellerFeeBasisPoints: 0,
42+
creators: null,
43+
collection: null,
44+
uses: null,
45+
};
46+
47+
const metadataPDAAndBump = PublicKey.findProgramAddressSync(
48+
[
49+
Buffer.from("metadata"),
50+
TOKEN_METADATA_PROGRAM_ID.toBuffer(),
51+
tokenMintAccount.toBuffer(),
52+
],
53+
TOKEN_METADATA_PROGRAM_ID
54+
);
55+
56+
const metadataPDA = metadataPDAAndBump[0];
57+
58+
const transaction = new Transaction();
59+
60+
const createMetadataAccountInstruction =
61+
createCreateMetadataAccountV3Instruction(
62+
{
63+
metadata: metadataPDA,
64+
mint: tokenMintAccount,
65+
mintAuthority: user.publicKey,
66+
payer: user.publicKey,
67+
updateAuthority: user.publicKey,
68+
},
69+
{
70+
createMetadataAccountArgsV3: {
71+
collectionDetails: null,
72+
data: metadataData,
73+
isMutable: true,
74+
},
75+
}
76+
);
77+
78+
transaction.add(createMetadataAccountInstruction);
79+
80+
const transactionSignature = await sendAndConfirmTransaction(
81+
connection,
82+
transaction,
83+
[user]
84+
);
85+
86+
const transactionLink = getExplorerLink(
87+
"transaction",
88+
transactionSignature,
89+
"devnet"
90+
);
91+
92+
console.log(`✅ Transaction confirmed, explorer link is: ${transactionLink}!`);
93+
94+
const tokenMintLink = getExplorerLink(
95+
"address",
96+
tokenMintAccount.toString(),
97+
"devnet"
98+
);
99+
100+
console.log(`✅ Look at the token mint again: ${tokenMintLink}!`);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { createMint } from "@solana/spl-token";
2+
import "dotenv/config";
3+
import {
4+
getKeypairFromEnvironment,
5+
getExplorerLink,
6+
} from "@solana-developers/helpers";
7+
import { Connection, clusterApiUrl } from "@solana/web3.js";
8+
9+
const connection = new Connection(clusterApiUrl("devnet"));
10+
11+
const user = getKeypairFromEnvironment("SECRET_KEY");
12+
13+
console.log(
14+
`🔑 Loaded our keypair securely, using an env file! Our public key is: ${user.publicKey.toBase58()}`
15+
);
16+
17+
// This is a shortcut that runs:
18+
// SystemProgram.createAccount
19+
// token.createInitializeMintInstruction
20+
// See https://www.soldev.app/course/token-program
21+
const tokenMint = await createMint(connection, user, user.publicKey, null, 2);
22+
23+
const link = getExplorerLink("address", tokenMint.toString(), "devnet");
24+
25+
console.log(`✅ Success! Created token mint: ${link}`);

project-3-tokens/mint-tokens.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { getOrCreateAssociatedTokenAccount, mintTo } from "@solana/spl-token";
2+
import "dotenv/config";
3+
import {
4+
getExplorerLink,
5+
getKeypairFromEnvironment,
6+
} from "@solana-developers/helpers";
7+
import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js";
8+
9+
// mintTo() doesn't default to a commitment level (unlike, say, sendAndConfirmTransaction() ), so we need to specify it
10+
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
11+
12+
// Our token has two decimal places
13+
const MINOR_UNITS_PER_MAJOR_UNITS = Math.pow(10, 2);
14+
15+
const user = getKeypairFromEnvironment("SECRET_KEY");
16+
17+
// Subtitute in your token mint account from create-token-mint.ts
18+
const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_HERE");
19+
20+
// Let's mint the tokens to ourselves for now!
21+
const recipientAssociatedTokenAccount = await getOrCreateAssociatedTokenAccount(
22+
connection,
23+
user,
24+
tokenMintAccount,
25+
user.publicKey
26+
);
27+
28+
const transactionSignature = await mintTo(
29+
connection,
30+
user,
31+
tokenMintAccount,
32+
recipientAssociatedTokenAccount.address,
33+
user,
34+
10 * MINOR_UNITS_PER_MAJOR_UNITS
35+
);
36+
37+
const link = getExplorerLink("transaction", transactionSignature, "devnet");
38+
39+
console.log(`✅ Success! Mint Token Transaction: ${link}`);
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import "dotenv/config";
2+
import {
3+
getExplorerLink,
4+
getKeypairFromEnvironment,
5+
} from "@solana-developers/helpers";
6+
import { Connection, PublicKey, clusterApiUrl } from "@solana/web3.js";
7+
import { getOrCreateAssociatedTokenAccount, transfer } from "@solana/spl-token";
8+
const connection = new Connection(clusterApiUrl("devnet"));
9+
10+
const sender = getKeypairFromEnvironment("SECRET_KEY");
11+
12+
console.log(
13+
`🔑 Loaded our keypair securely, using an env file! Our public key is: ${sender.publicKey.toBase58()}`
14+
);
15+
16+
// Add the recipient public key here
17+
const recipient = new PublicKey("YOUR_RECIPIENT_HERE");
18+
19+
// Subtitute in your token mint account
20+
const tokenMintAccount = new PublicKey("YOUR_TOKEN_MINT_ADDRESS_HERE");
21+
22+
// Our token has two decimal places
23+
const MINOR_UNITS_PER_MAJOR_UNITS = Math.pow(10, 2);
24+
25+
console.log(`💸 Attempting to send 1 token to ${recipient.toBase58()}...`);
26+
27+
// Get or create the source and destination token accounts to store this token
28+
const sourceTokenAccount = await getOrCreateAssociatedTokenAccount(
29+
connection,
30+
sender,
31+
tokenMintAccount,
32+
sender.publicKey
33+
);
34+
35+
const destinationTokenAccount = await getOrCreateAssociatedTokenAccount(
36+
connection,
37+
sender,
38+
tokenMintAccount,
39+
recipient
40+
);
41+
42+
// Transfer the tokens
43+
const signature = await transfer(
44+
connection,
45+
sender,
46+
sourceTokenAccount.address,
47+
destinationTokenAccount.address,
48+
sender,
49+
1 * MINOR_UNITS_PER_MAJOR_UNITS
50+
);
51+
52+
const explorerLink = getExplorerLink("transaction", signature, "devnet");
53+
54+
console.log(`✅ Transaction confirmed, explorer link is: ${explorerLink}!`);

0 commit comments

Comments
 (0)