Jacky Gu

Solana开发笔记: 使用前端SDK创建Mint代币

01 Jan 2025 Share to

使用前端SDK创建Mint代币

前面一篇中,详细介绍了用anchor创建SPL代币,在这篇中,使用前端SDK来创建一个代币程序。

代码如下:

import * as web3 from "@solana/web3.js";
import * as token from "@solana/spl-token";
import { createCreateMetadataAccountV3Instruction } from "@metaplex-foundation/mpl-token-metadata"; // V2
// 注意:必须安装 @metaplex-foundation/mpl-token-metadata 版本V2,不能是V3

type Metadata = {
  name: string;
  symbol: string;
  uri: string;
  sellerFeeBasisPoints?: number;
  creators?: {
    address: string;
    share: number;
  }[];
  collection?: {
    name: string;
    family: string;
  }[];
  uses?: {
    use: string;
    remaining: number;
    total: number;
  }[];
}

const initializeTokenMint = async (connection: web3.Connection, user: web3.Keypair): Promise<web3.PublicKey> => {
  const tokenMint = await token.createMint(
    connection,
    user,
    user.publicKey,
    null,
    6,
  );
  return tokenMint;
}

const setMetadata = async (
  connection: web3.Connection,
  user: web3.Keypair,
  tokenMintAccount: web3.PublicKey,
  metadata: Metadata,
): Promise<string> => {
  const TOKEN_METADATA_PROGRAM_ID = new web3.PublicKey(
    "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s",
  );
  const metadataData = {
    name: metadata.name,
    symbol: metadata.symbol,
    // Arweave / IPFS / Pinata etc link using metaplex standard for offchain data
    uri: metadata.uri,
    sellerFeeBasisPoints: 0,
    creators: null,
    collection: null,
    uses: null,
  };

  const metadataPDAAndBump = web3.PublicKey.findProgramAddressSync(
    [
      Buffer.from("metadata"),
      TOKEN_METADATA_PROGRAM_ID.toBuffer(),
      tokenMintAccount.toBuffer(),
    ],
    TOKEN_METADATA_PROGRAM_ID,
  );
  const metadataPDA = metadataPDAAndBump[0];
  const transaction = new web3.Transaction();

  transaction.add(
    createCreateMetadataAccountV3Instruction(
      {
        metadata: metadataPDA,
        mint: tokenMintAccount,
        mintAuthority: user.publicKey,
        payer: user.publicKey,
        updateAuthority: user.publicKey,
      },
      {
        createMetadataAccountArgsV3: {
          collectionDetails: null,
          data: metadataData,
          isMutable: true,
        },
      },
    )
  )

  const transactionSignature = await web3.sendAndConfirmTransaction(
    connection,
    transaction,
    [user],
  );
  return transactionSignature;
}

const createTokenMint = async (): Promise<{ tokenMintAccount: web3.PublicKey, tx: string }> => {
  // 第一步:初始化tokenMint
  const tokenMintAccount = await initializeTokenMint(connection, user);
  const metadata = {
    name: "Test POM Token",
    symbol: "POM",
    uri: "https://arweave.net/1234"
  };
  // 第二步:设置metadata
  const transactionLink = await setMetadata(
    connection,
    user,
    new web3.PublicKey(tokenMintAccount),
    metadata,
  );
  return { tokenMintAccount: tokenMintAccount, tx: transactionLink };
}

// 创建完Token后,铸造:
const mintToken = async (
  connection: web3.Connection,
  user: web3.Keypair,
  tokenMintAccount: web3.PublicKey,
  toAccount: web3.PublicKey,
  amount: number
): Promise<string> => {
  const tokenAccount = await token.getOrCreateAssociatedTokenAccount(
    connection,
    user,
    tokenMintAccount,
    toAccount,
  );

  const transactionSignature = await token.mintTo(
    connection,
    user,
    tokenMintAccount,
    tokenAccount.address,
    user,
    amount * 10**6, // decimals = 6
  );
  return transactionSignature;
}

const connection = new web3.Connection(web3.clusterApiUrl("devnet"), "confirmed");
const user = getKeypairFromEnvironment("SECRET_KEY");

// 1. 创建tokenMint,得到 9a67ocRia9yUotN6YCveC6Kp8YyxocjCsuemrRkPrFLq
const result = await createTokenMint();
console.log(`✅ Finished! Created metadata: ${getExplorerLink("transaction", result.tx, "devnet")}`);
console.log(`✅ Look at the token mint again: ${getExplorerLink("address", result.tokenMintAccount.toString(), "devnet")}`);

// 2. 铸造代币
const toAccount = new web3.PublicKey(process.env.ADDRESS as string);
const mintResult = await mintToken(connection, user, tokenMintAccount, toAccount, 20);
console.log(`✅ Finished! Minted token: ${getExplorerLink("transaction", mintResult, "devnet")}`);